#include "StdAfx.h"
#include "nlib_include.h"



HINTERNET hHttpSession;			//HINTERNET
HINTERNET hWatchLiveNicoConnect;
HINTERNET hNicoVideoConnect;

TCHAR appDataPath[_MAX_PATH];
TCHAR localAppDataPath[_MAX_PATH];
XML_Parser xmlParser;
static CRITICAL_SECTION playerStatusParserCs;


///
///プレイヤーステータスパーサ初期化
///
static INLINE VOID Parser_Initialize();


///
///プレイヤーステータスパーサ後処理
///
static INLINE VOID Parser_Finalize();

NLIB_RESULT InitializeNLIB(HINTERNET hInternet){

	NLIB_RESULT rslt = NLIB_ERR_CODE_NOTSET;
	hHttpSession = hInternet;
	if(hHttpSession == NULL){

		rslt = NLIB_INITALIZE_FAILED_NETWORK;
		goto end;

	}

	hWatchLiveNicoConnect = WinHttpConnect(hHttpSession,WTEXT(WATCH_LIVE_NICO_VIDEO_DOMEINNAME),INTERNET_DEFAULT_HTTP_PORT,0);

	if(hHttpSession == NULL){
		rslt = NLIB_INITALIZE_FAILED_NETWORK;
		goto end;
	}

	hNicoVideoConnect = WinHttpConnect(hHttpSession,WWW_NICO_VIDEO_DOMEINNAME,INTERNET_DEFAULT_HTTP_PORT,0);

	//appDataのパスをセット
	SHGetFolderPathW(0,CSIDL_APPDATA,0,SHGFP_TYPE_CURRENT,appDataPath);
	wcscat(appDataPath,L"\\");

	//localAppDataのパスをセット
	SHGetFolderPathW(0,CSIDL_LOCAL_APPDATA,0,SHGFP_TYPE_CURRENT,localAppDataPath);
	wcscat(localAppDataPath,L"\\");




	//クッキーライブラリを初期化
	InitializeShareCookie(appDataPath,localAppDataPath);

	Initialize_NicoLive();

	//パーサを初期化
	Parser_Initialize();

	rslt = NLIB_ERR_OK;

end:


	return rslt;
}

VOID FinalizeNLIB(){
	//プレイヤーステータスパーサ後処理
	Parser_Finalize();

	Finalize_NicoLive();


	//クッキー共有ライブラリの後処理
	FinalizeShareCookie();



	//winHttpの後処理
	//WinHttpCloseHandle(hHttpSession);

	//winsockの後処理
	//WSACleanup();

	return;
}


INLINE BOOL ReadHttpBody(HINTERNET hRequest,LPBYTE lpBuffer,DWORD dwBufSize,LPDWORD lpDwSize){


	DWORD  dwSize;
	DWORD  dwTotalSize = 0;
	DWORD  dwTotalSizePrev = 0;

	for (;;) {
		WinHttpQueryDataAvailable(hRequest, &dwSize);
		if (dwSize > 0) {
			dwTotalSizePrev = dwTotalSize;
			dwTotalSize += dwSize;

			if(dwTotalSize >= dwBufSize){
				return FALSE;
			}

			WinHttpReadData(hRequest, lpBuffer + dwTotalSizePrev, dwSize, (LPDWORD)NULL);

		}
		else
			break;
	}

	*lpDwSize= dwTotalSize;

	return TRUE;

}
static INLINE VOID Parser_Initialize(){


	xmlParser = XML_ParserCreate((const XML_Char*)NULL);

	check(xmlParser,TEXT("パーサ初期化に失敗しました"));



	InitializeCriticalSection(&playerStatusParserCs);

}

static INLINE VOID Parser_Finalize(){


	XML_ParserFree(xmlParser);

	DeleteCriticalSection(&playerStatusParserCs);


}

 NLIB_RESULT XMLParse(LPVOID option,LPCSTR body,XML_StartElementHandler startElementEvent,XML_EndElementHandler endElementEvent,XML_CharacterDataHandler characterDataEvent){

	UserDataContainer userDataContainer;
	userDataContainer.nord = 0;
	userDataContainer.userData = option;
	userDataContainer.errcode = NLIB_ERR_CODE_NOTSET;

	EnterCriticalSection(&playerStatusParserCs);

	//属性設定
	XML_SetElementHandler(xmlParser,startElementEvent,endElementEvent);
	XML_SetCharacterDataHandler(xmlParser,characterDataEvent);
	XML_SetUserData(xmlParser,&userDataContainer);

	//解析
	XML_Parse(xmlParser,body,strlen(body),TRUE);

	//リセット
	XML_ParserReset(xmlParser,(const XML_Char*)NULL);

	LeaveCriticalSection(&playerStatusParserCs);

	return userDataContainer.errcode;
}


 NLIB_RESULT HttpXMLParse(LPVOID userData,LPCTSTR userSession,HINTERNET hConnect,XML_StartElementHandler startElementEvent,XML_EndElementHandler endElementEvent,XML_CharacterDataHandler characterDataEvent){

	 NLIB_RESULT rslt = NLIB_ERR_CODE_NOTSET;
	const UINT_PTR buflen = LENGTH_65536;
	LPVOID buffer = malloc(buflen * 3);
	{
		
		
		
		LPSTR recvBuffer = (LPSTR)buffer;
		DWORD readSize;
		DWORD statusCode;
		DWORD statusCodeSize = sizeof(statusCode);


	

		if(WinHttpSendRequest(hConnect,userSession,-1,WINHTTP_NO_REQUEST_DATA,0,0,0) == FALSE){

			goto networkerr;

		}

		if(WinHttpReceiveResponse(hConnect,NULL) == FALSE){

			goto networkerr;

		}


		if (WinHttpQueryHeaders(hConnect,WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,WINHTTP_HEADER_NAME_BY_INDEX,&statusCode,&statusCodeSize,WINHTTP_NO_HEADER_INDEX) == FALSE){
			goto networkerr;
		}


		if (HTTP_STATUS_OK != statusCode){
			goto networkerr;
		}




		if(ReadHttpBody(hConnect,(LPBYTE)recvBuffer,buflen,&readSize) == FALSE){

			goto networkerr;

		}

		recvBuffer[readSize] = '\0';

		recvBuffer = strstr(recvBuffer,"<");

		if(recvBuffer == NULL){
			
			goto networkerr;
		}


		rslt = XMLParse(userData,recvBuffer,startElementEvent,endElementEvent,characterDataEvent);
		
		if(rslt != NLIB_ERR_OK){

			goto end;
		}
	}

end:
	free(buffer);
	

	

	return rslt;

networkerr:
	rslt = NLIB_FAILED_CONNECT;

	goto end;
 }