/* Copyright 2013 Akira Ohta (akohta001@gmail.com)
    This file is part of ntch.

    The ntch is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    The ntch is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ntch.  If not, see <http://www.gnu.org/licenses/>.
    
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <wchar.h>
#include <assert.h>
#include <iconv.h>

#include "env.h"
#include "utils/nt_std_t.h"
#include "utils/text.h"
#include "utils/nt_conv_char.h"
#include "_2ch/model_2ch.h"
#include "_2ch/search_2ch.h"
#include "net/nt_http.h"

#define NT_SEARCH_URL_REFERER "http://find.2ch.net/"
#define NT_SEARCH_URL "http://find.2ch.net/?STR=%s&SCEND=A&SORT=MODIFIED&COUNT=50&TYPE=TITLE&BBS=ALL"

static nt_searched_thread_tp parse_searched_thread(
			nt_2ch_model_tp modelp, wchar_t *line);

BOOL nt_get_search_text(const char *in_text, char** out_text)
{
	const char *start, *end;
	int len;
	char *cptr;
	
	if(!nt_strtok(in_text, ' ', &start, &end))
		return FALSE;
	
	len = end - start;
	if(len <= 0)
		return FALSE;
	
	if(0 != strncmp(NT_COMMAND1_SEARCH_1, start, len) &&
			0 != strncmp(NT_COMMAND1_SEARCH_2, start, len))
		return FALSE;
	if(0 < strlen(end)){
		cptr = nt_trim(end);
		if(!cptr)
			return FALSE;
		*out_text = cptr;
	}else{
		*out_text = NULL;
	}
	return TRUE;
}

nt_link_tp nt_search_all_board(nt_2ch_model_tp modelp, 
			const char *search_text, const wchar_t** error_msg)
{
	char *url;
	
	FILE *tmp_fp;
	pid_t pid;
	char fname[512];
	nt_link_tp linkp, result_list;
	char buf[1024];
	char buf2[512];
	wchar_t wc[1024];
	iconv_t icd;
	nt_searched_thread_tp threadp;
	//int len, ret;
	
	assert(error_msg);
	
	result_list = NULL;
	*error_msg = NULL;
	
	if(!search_text || strlen(search_text) == 0){
		*error_msg = L"検索文字列が指定されていません";
		return NULL;
	}
	
	icd =   iconv_open("EUC-JP", "UTF-8");
	if(((iconv_t)-1) == icd){
		*error_msg = L"文字コードの変換に失敗しました";
		return NULL;
	}
	if(!nt_conv_local2sjis(icd, search_text, buf, sizeof(buf))){
		*error_msg = L"文字コードの変換に失敗しました";
		return NULL;
	}
	iconv_close(icd);
	
	if(!url_encode(buf, buf2, sizeof(buf2))){
		*error_msg = L"URLエンコードに失敗しました";
		return NULL;
	}
	
	pid = getpid();

	sprintf(fname, "%s/msg%d.tmp", LOG_PATH, pid);
	tmp_fp = fopen(fname, "w");
	if(!tmp_fp){
		*error_msg = L"テンポラリファイルの作成に失敗しました";
		return NULL;
	}
	fclose(tmp_fp);
	
	url = malloc(strlen(NT_SEARCH_URL) + strlen(buf2) + 1);
	if(!url){
		*error_msg = L"メモリーエラー";
		return NULL;
	}
	
	sprintf(url, NT_SEARCH_URL, buf2);
	
	if(!nt_http_get(url, fname, NT_SEARCH_URL_REFERER,
			NULL, NULL, FALSE, TRUE)){
		*error_msg = L"ネットワーク接続に失敗しました";
		free(url);
		return NULL;
	}
	
	tmp_fp = fopen(fname, "r");
	if(!tmp_fp){
		*error_msg = L"テンポラリファイルの作成に失敗しました";
		free(url);
		return NULL;
	}
	
	icd =   iconv_open("wchar_t","EUC-JP");
	if(((iconv_t)-1) == icd){
		*error_msg = L"文字コードの変換に失敗しました";
		goto ERROR_TRAP;
	}
	while(fgets(buf, sizeof(buf), tmp_fp)){
		if(!nt_conv_sjis2wc(icd, buf, wc, 
					sizeof(wc)*sizeof(wchar_t))){
			//*error_msg = L"文字コードの変換に失敗しました";
			//iconv_close(icd);
			//goto ERROR_TRAP;
		}else{
			threadp = parse_searched_thread(modelp, wc);
			if(threadp){
				linkp = nt_link_add_data(result_list, threadp);
				if(!result_list)
					result_list = linkp;
			}
		}
	}
	iconv_close(icd);
ERROR_TRAP:
	fclose(tmp_fp);
	unlink(fname);
	free(url);
	return result_list;
}

		
static nt_searched_thread_tp parse_searched_thread(
			nt_2ch_model_tp modelp, wchar_t *line)
{
	nt_searched_thread_tp threadp;
	nt_board_tp boardp;
	wchar_t *cptr, *cptr2;
	wchar_t *board_name, *dat, *title;
	int len1, len2, len3;
	
	assert(line);
	cptr = wcsstr(line, L"<dt><a href=\"");
	if(!cptr)
		return NULL;
	cptr += wcslen(L"<dt><a href=\"");
	
	cptr = wcsstr(cptr, L"test/read.cgi/");
	if(!cptr)
		return NULL;
	cptr += wcslen(L"test/read.cgi/");
	
	cptr2 = wcsstr(cptr, L"/");
	if(!cptr2)
		return NULL;
	*cptr2 = L'\0';
	cptr2++;
	
	boardp = nt_get_board_by_address_match(modelp, cptr);
	if(!boardp){
		return NULL;
	}
	board_name = boardp->name;
	
	cptr = wcsstr(cptr2, L"/");
	if(!cptr)
		return NULL;
	*cptr = L'\0';
	cptr++;
	
	dat = cptr2;
	
	cptr2 = wcsstr(cptr, L">");
	if(!cptr2)
		return NULL;
	cptr2++;
	
	cptr = wcsstr(cptr2, L"</a>");
	if(!cptr)
		return NULL;
	*cptr = L'\0';
	
	title = cptr2;
	
	threadp = malloc(sizeof(nt_searched_thread_t));
	if(!threadp)
		return NULL;
		
	len1 = wcslen(board_name)+1;
	len2 = wcslen(dat)+5;
	len3 = wcslen(title)+1;
	
	threadp->board_name = malloc((len1 + len2 + len3)*sizeof(wchar_t));
	if(!threadp->board_name){
		free(threadp);
		return NULL;
	}
	wcscpy(threadp->board_name, board_name);

	threadp->dat_name = threadp->board_name + len1;
	wcscpy(threadp->dat_name, dat);
	cptr = wcsstr(dat, L".");
	if(!cptr)
		wcscat(threadp->dat_name, L".dat");

	threadp->title = threadp->dat_name + len2;
	wcscpy(threadp->title, title);
	
	return threadp;
}

void free_searched_thread(void *ptr)
{
	assert(ptr);
	nt_searched_thread_tp threadp;
	threadp = (nt_searched_thread_tp)ptr;
	free(threadp->board_name);
	free(threadp);
}



