/* DIVIDE_START=search.c */
/*
	ＮＩＦＴＹのＬＯＧ整理				search.c
*/

#include	"catlog.h"

struct	ID_NAME	{
			char		id[ 9 ];	/* ID名 */
			char		name[ 17 ];	/* ハンドル */
			int			num;		/* 出てきた回数 */
};

static	struct	ID_NAME	*search_id_name;
static	int		max_search_id_name;

/* 文字列の最後の空白を削除 漢字にも対応 */
void	erase_last_spase( char *str )
{
	char	*p;

	p = str + strlen( str );
	while ( p >= str ) {
		if ( *p != ' ' ) {
					if ( *p != 0x40 )				break;
					if ( p <= str )					break;
			p--;	if ( ( *p & 0xff ) != 0x81 )	break;
		};
		*p = '\0';	p--;
	};
}

static	void	search_id_name_malloc()
{
	size_t	max,min,tmp;

	/*****************************************************************/
	/* malloc() を使って struct ID_NAME search_id_name[] の領域を確保する */
	/*****************************************************************/
	max = 300000;	min = 0;	tmp = ( max - min ) / 2 + min;
	forever {
		if (	( search_id_name =
			(struct ID_NAME *)malloc( tmp * sizeof(struct ID_NAME) )
		) == NULL ) {	max = tmp;
		} else {	min = tmp;	free( search_id_name );
		};
		tmp = ( max - min ) / 2 + min;
		if ( max == min || max - 1 == min )	break;
	};
	search_id_name = (struct ID_NAME *)malloc( tmp * sizeof(struct ID_NAME) );
	max_search_id_name = (int)tmp;

	mess_check	printf("\n%d 個までのＩＤを処理できます" , max_search_id_name );
}

static	int		search_id_name_sub( char *id , char *name )
{
	int		i;
	char	*p1 , *p2;

	p1 = search_id_name[ save_end ].id;			p2 = id;
	for ( i=0 ; i<8 ; i++ ) *p1++ = *p2++;		/* ８バイト */
	*p1 = '\0';
	p1 = search_id_name[ save_end ].name;		p2 = name;
	for ( i=0 ; i<8*2 ; i++ ) *p1++ = *p2++;	/* 漢字で８文字 */
	*p1 = '\0';

	for ( i=0 ; i<save_end ; i++ ) {
		if ( strcmp(search_id_name[i].id  ,search_id_name[save_end].id  ) == 0
		&&	 strcmp(search_id_name[i].name,search_id_name[save_end].name) == 0
		) {
			search_id_name[ i ].num++;		/* 出てきた回数 */
			return( TRUE );
		};
	};
	/* 初めて出て来た */
	search_id_name[ save_end ].num = 1;
	if ( save_end < max_search_id_name - 1 ) {	save_end++;	return( TRUE );	};
	return( FALSE );
}

static	void	search_id_name_mail( const char *f_name )
{
	forever {
		CPDS = PSP;
		GET_LINE2	break;								/* 先読み */
		if ( isMailFirstLine() == NO )	continue;

		/*           1         2         3         4   */
		/*  123456789 123456789 123456789 123456789 12 */
		/*  1  山本　年秀　　　  NAA02244  05/05 13:12 */
		/*  2 #飛雪              NAA02244  06/02 21:56 */

		if ( search_id_name_sub( PSP + 22 , PSP + 4 ) != TRUE )
			break;
	};
}

static	void	search_id_name_forum( const char *f_name )
{
	int		add;

	forever {
		CPDS = PSP;
		GET_LINE2	break;								/* 先読み */
		if ( isMesHyoudaiLine() == NO )	continue;
		if ( isMesSecondLine() == NO )	continue;

		/*           1         2         3         4          */
		/* 0123456789 123456789 123456789 123456789 1234567   */
		/* 000/000   NAA02244  飛雪              最近の楽しみ */
		/* 000/000   NAA02244  1 2 3 4 5 6 7 8   最近の楽しみ */
		/* 000/000   ********                    SYSOP 削除   */
		/* 00001/00011 NAA02244  飛雪             MESを選択後 */

		if ( PSP[3] == '/' ) {		add = 0;
		} else {								add = 2;
		};

		if ( search_id_name_sub( PSP + 10 + add , PSP + 20 + add ) != TRUE )
			break;
	};
}

static	void
search_id_name_loop_sub( const char *f_name , const char *ff_name )
{
	int		done , f_size;

	if ( save_end >= max_search_id_name )	return;

	done = isCATLOGFile( f_name );
	if (	done != 0
	&&		done != BILL
	&&		done != LIB
	&&		done != HP
	&&		done != COLLECT_ID
	) {
		f_size = _get_file_size( f_name );
		if ( f_size > 0 ) {
			mess_check printf("\n<%s>を調べます",f_name);
			save_start = save_end;
			strcpy( file_name , f_name );
			initial_check_pool( f_size , NO /* append 0x0a switch */ );
			if ( done == MAIL ) {		search_id_name_mail( f_name );
			} else {					search_id_name_forum( f_name );
			};
			end_check_pool();
			printf("%4d 個 追加" , save_end - save_start );
		};
	};
}

int	search_id_name_cmp1( const void *p11 , const void *p21 )
{
	const struct ID_NAME *p1 = p11;
	const struct ID_NAME *p2 = p21;

	return( strcmp( p1->id , p2->id ) );
}

int	search_id_name_cmp2( const void *p11 , const void *p21 )
{
	const struct ID_NAME *p1 = p11;
	const struct ID_NAME *p2 = p21;

	return( p2->num - p1->num );
/*
	return( p1->num - p2->num );
*/
}

/**************************************/
/* ＩＤとハンドルの対応ファイルを作る */
/**************************************/
#define	ID_HANDLE_FORMAT	"%8s → %16s %4d 回\n"
void	search_id_name_main( const char *out_file )
{
	int		i;
	char	*p;

	mess_check	printf( "\nＩＤ−ハンドル表を作ります" );

	/* 初期化 */
	search_id_name_malloc();
	save_start = save_end = 0;

	/* 1994.2.12 追加 out_file から ID-Handle 表を読み込む */
	if ( ( catlog_fpi = fopen( out_file , "r" ) ) != NULL ) {
		mess_check printf( "\n<%s>から対応表を読み込みます → ", out_file);
		while ( fgets( str, LINE, catlog_fpi ) != NULL ) {
			if ( strncmp( str, "-----", 5 ) == 0 )	break;
			str[8]= '\0';
			if ( isIDname( str ) != YES )			continue;
			p= skip_space( str + 9 );
			if ( strncmp( p, "→", 2 ) == 0 )		p= skip_space( p + 2 );
			if ( *p == '\0' )						continue;
			strcpy(	 search_id_name[ save_end ].id, str );
			strncpy( search_id_name[ save_end ].name, p, 16 );
			search_id_name[ save_end ].name[16] = '\0';
			search_id_name[ save_end ].num = 0;
			if ( save_end < max_search_id_name -1 )		save_end++;
		};
		fclose( catlog_fpi);
		mess_check	printf( "%d 個のデータがありました", save_end );
	};

	/* 整理済みのファイルを検索 */
	catlog_findfirst_mes_sw = NO;
	catlog_findfirst( OutDir, search_id_name_loop_sub, YES, YES );

	/* IDでソート */
	qsort(search_id_name,save_end,sizeof(struct ID_NAME),search_id_name_cmp1);

	/* ファイルに書き出す */
	if ( ( catlog_fpo = fopen( out_file , "w" ) ) == NULL ) {
		strcpy( file_name , out_file );
		error_open_file( "search_id_name_main(write)" );		return;
	};
	for ( i=0 ; i<save_end ; i++ ) {
		fprintf( catlog_fpo ,ID_HANDLE_FORMAT,
			search_id_name[ i ].id,
			search_id_name[ i ].name,
			search_id_name[ i ].num
		);
	};
	/* 発言回数でソート */
	qsort(search_id_name,save_end,sizeof(struct ID_NAME),search_id_name_cmp2);
	fprintf( catlog_fpo , "------------------------------------------\n" );
	for ( i=0 ; i<save_end ; i++ ) {
		fprintf( catlog_fpo ,ID_HANDLE_FORMAT,
			search_id_name[ i ].id,
			search_id_name[ i ].name,
			search_id_name[ i ].num
		);
	};
	fclose( catlog_fpo );
	free( search_id_name );		/* 使った領域を開放する */

	mess_check	printf( "\nＩＤ−ハンドル表 作成を終了しました" );
}

/***************************************************************************/

static	void	search_id_mes_save_start_sub( )
{
	/* collect.c                                     */
	/* ディスクの残り容量によって divide_main を呼ぶ */
	/* divide_main では file_name が破壊される */
	check_drive_space( 80*300+1024 );

	catlog_fprintf( partition_line );
	catlog_fprintf( ForumName );						/* フォーラム名 */
	sprintf( str , "%d" , MesNum );
	catlog_fprintf( str );								/* 会議室番号 */
	sprintf( str , "%d" , HatsugenNumber );
	catlog_fprintf( str );								/* 発言番号 */
	catlog_fprintf( HatsugenDate );					/* 発言の日付 */
	sprintf( str , "%d" , CommentNumber );
	catlog_fprintf( str );								/* コメント番号 */
	catlog_fprintf( CollectId );						/* 発言の収集ＩＤ */
	catlog_fprintf( ForumNameLine );					/* フォーラム名の行 */
	catlog_fprintf( ForumNameLineSub );				/* フォーラム名の行 */

	hatugen_su++;		/* 1つのﾌｧｲﾙの発言の数 */
}

/*****************************************************************/
/* CATLOGを使って整理したﾌｧｲﾙからIDによって発言を収集する(ﾌｫｰﾗﾑ) */
/*****************************************************************/
static	void	search_id_mes_forum( )
{
	char	*p1;

	GET_LINE2	;	/* Resort by CATLOG */
	GET_LINE2	;
	present_str_copy( ForumNameLine );
	GET_LINE2	;
	present_str_copy( ForumNameLineSub );
	GET_LINE2	;	/* 先読み */
	forever {
		if ( PSP == NULL )				break;		/* EOF */
		IFPStrEqu2( "*****log整理",12) {
			present_str_copy( partition_line );
			GET_LINE2	break;								/* 先読み */
		};
		if ( isMesForumNameLine() == YES ) {
			present_str_copy( ForumNameLine );
			GET_LINE2	break;								/* 先読み */
		};
		if ( isMesHyoudaiLine() == NO || isMesSecondLine() == NO ) {
			GET_LINE2	break;								/* 先読み */
			continue;
		};
		if ( PSP[ 3 ] == '/' ) {	p1 = PSP + 10;
		} else {							p1 = PSP + 12;
		};
		if ( isCollectID( p1 ) < 0 ) {		/* sub.c */
			GET_LINE2	break;								/* 先読み */
			continue;
		};

		CPDS = PSP;
		HatsugenNumber = atoi( PSP );

		GET_LINE2	break;	/* 会議室番号の行 */

		/* 日付 */
		set_hatsugen_date_forum( PSP );

		/* コメント番号 */
		if (	PSL > 21
		&&		isdigit( PSP[23] )
		) {			CommentNumber = atoi( PSP + 23 );
		} else {	CommentNumber = 0;
		};

		GET_LINE2	break;									/* 先読み */
		while (	strncmp( PSP , "*****log整理" , 12 ) != 0
		&&		isMesForumNameLine() == NO
		&&		isMesHyoudaiLine() == NO
		) {
			GET_LINE2	break;								/* 先読み */
		};
		search_id_mes_save_start_sub( );
		if ( catlog_fwrite( ) == 0 ) {
			error_bug( "書き込みが出来ませんでした(search_id_mes_forum)" );
		};
	};
}

/*****************************************************************/
/* CATLOGを使って整理したﾌｧｲﾙからIDによって発言を収集する(ﾒｰﾙ)   */
/*****************************************************************/
static	void	search_id_mes_mail( )
{
	sprintf( ForumNameLine , "- MAIL:%sからのメールです。", ForumName );
	ForumNameLineSub[ 0 ] = '\0';
	GET_LINE2	;	/* Resort by CATLOG */
	GET_LINE2	;	/* 先読み */
	forever {
		if ( PSP == NULL )				break;		/* EOF */
		IFPStrEqu2( "*****log整理",12) {
			present_str_copy( partition_line );
			GET_LINE2	break;								/* 先読み */
		};
		if ( isMailFirstLine() == NO ) {
			GET_LINE2	break;								/* 先読み */
			continue;
		};
		CPDS = PSP;
		HatsugenNumber = atoi( PSP );

		/* 日付 */
		set_hatsugen_date_mail( PSP );

		GET_LINE2	break;									/* 先読み */
		while (	strncmp( PSP , "*****log整理" , 12 ) != 0
		&&		isMailFirstLine() == NO
		) {
			GET_LINE2	break;								/* 先読み */
		};
		search_id_mes_save_start_sub( );
		if ( catlog_fwrite( ) == 0 ) {
			error_bug( "書き込みが出来ませんでした(search_id_mes_mail)" );
		};
	};
}

/*****************************************************************/
/* CATLOGを使って整理したﾌｧｲﾙからIDによって発言を収集する( HP )  */
/*****************************************************************/
static	void	search_id_mes_hp( )
{
	sprintf( ForumNameLine , "- HP:%sのHome Partyです。" , ForumName );
	ForumNameLineSub[ 0 ] = '\0';
	GET_LINE2	;	/* Resort by CATLOG */
	GET_LINE2	;	/* 先読み */
	forever {
		CPDS = PSP;
		if ( PSP == NULL )				break;		/* EOF */
		IFPStrEqu2( "*****log整理",12) {
			present_str_copy( partition_line );
			GET_LINE2	break;								/* 先読み */
		};
		if ( isHPFirstLine() == NO ) {
			GET_LINE2	break;								/* 先読み */
			continue;
		};
		if ( isCollectID( PSP + 23 ) < 0 ) {			/* sub.c */
			GET_LINE2	break;								/* 先読み */
			continue;
		};
		CPDS = PSP;
		HatsugenNumber = atoi( PSP );			/* 発言番号 */

		/* 日付 */
		set_hatsugen_date_hp( PSP );

		GET_LINE2	break;									/* 先読み */
		while (	strncmp( PSP , "*****log整理" , 12 ) != 0
		&&		isHPFirstLine() == NO
		) {
			GET_LINE2	break;								/* 先読み */
		};
		search_id_mes_save_start_sub( );
		if ( catlog_fwrite( ) == 0 ) {
			error_bug( "書き込みが出来ませんでした(search_id_mes_hp)" );
		};
	};
}

/*****************************************************************/
/* CATLOGを使って整理したﾌｧｲﾙからIDによって発言を収集する( LIB ) */
/*****************************************************************/
static	void	search_id_mes_lib( )
{
	/*
		MesNum : LIB
		HatsugenNumber    : lib_num
	*/

	GET_LINE2	;	/* FORUM:xxxxx LIB:dd */
	GET_LINE2	;	/* ＜………＞   FFMxxx */
	present_str_copy( ForumNameLine );
	ForumNameLineSub[ 0 ] = '\0';
	forever {
		CPDS = PSP;
		if ( PSP == NULL )				break;		/* EOF */
		IFPStrEqu2( "*****log整理",12) {
			present_str_copy( partition_line );
			GET_LINE2	break;								/* 先読み */
		};
		if ( isLIBLine() == NO ) {
			GET_LINE2	break;								/* 先読み */
			continue;
		};
/****************************************************************************
＞          1         2         3         4         5
＞ 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
＞ 343  NAA02244 92/06/08   57903   19 B CATLOG06.EXE NIFTY通信ログ編集ﾌﾟﾛｸﾞﾗﾑ
*****************************************************************************/
		if ( isCollectID( PSP + 6 ) < 0 ) {			/* sub.c */
			GET_LINE2	break;								/* 先読み */
			continue;
		};
		CPDS = PSP;

		/* 日付 */
		set_hatsugen_date_lib( PSP );

		MesNum = COLLECT_LIB;

		GET_LINE2	break;									/* 先読み */
		search_id_mes_save_start_sub( );
		if ( catlog_fwrite( ) == 0 ) {
			error_bug( "書き込みが出来ませんでした(search_id_mes_lib)" );
		};
	};
}

void	search_id_mes_loop_file( const char *f_name , const char *ff_name )
{
	int		d , f_size;

	f_size = _get_file_size( f_name );	if ( f_size <= 0 )	return;

	d = isCATLOGFile( f_name );						/* makeidx.c */
	if ( d == 0 )									return;	/* 無視する */
	if ( d < 0 ) {
		if ( d == MAIL || d == ALL_MAIL ) {
			if ( WithoutMAILSaySw == YES )		return;	/* 無視する */
			if ( isCollectID( ForumName ) < 0 )	return;	/* sub.c */
		} else if ( d == HP ) {
			if ( WithoutHPSaySw == YES )			return;	/* 無視する */
		} else if ( d == LIB ) {
			if ( WithoutLIBSaySw == YES )		return;	/* 無視する */
		} else {
				return;	/* 無視する */
		};
	} else {		/* MES */
			if ( WithoutMESSaySw == YES )		return;	/* 無視する */
	};

	sprintf(partition_line,"*****log整理(%s)***** %s *****",Version,f_name);
	CommentNumber = 0;					/* コメント先番号 */

	disp_start_check_file( ff_name , f_size );

	strcpy( file_name , f_name );
	initial_check_pool( f_size , NO /* append 0x0a switch */ );
	if ( d > 0 || d == PATIO ) {		search_id_mes_forum( );
	} else if ( d == MAIL ) {			search_id_mes_mail( );
	} else if (	d == HP ) {				search_id_mes_hp( );
	} else if (	d == LIB ) {			search_id_mes_lib( );
	};
	end_check_pool();

	f_size = ftell( catlog_fpo );
	disp_end_check_file( f_size );
}

/*************************************/
/* Collect_ID によって発言を収集する */
/*************************************/
void	search_id_mes_main( const char *path )
{
	if ( DoStage1Sw == NO )			return;
	print_now_time();
	CollectFileNumber = CollectFileSize = AllHatsugenSu = 0;
	open_out_tmp0_file();
	catlog_findfirst_mes_sw = YES;
	catlog_findfirst( path, search_id_mes_loop_file, YES, YES );
	fclose( catlog_fpo );

	if ( DoStage2Sw == YES )			divide_main();
	if ( BreakCatlogSw == NO ) {
		if ( DoStage3Sw == YES )		catlog_main();
	};
	print_now_time();
}

/* DIVIDE_END */
