#include "stdafx.h"
#include "emule.h"
#include "eMuleFuture.h" 
#include "Preferences.h" //for username/pw
#include "wininet.h" //for internet functionality
#include "otherfunctions.h" //for "GetErrorMessage()"
#include "./AntiLeech/Modname.h" //for the Modname used as agent
#include "log.h" //to enable logging

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CString CallModFunction(const uint8& uiFuncType)
{
	CString strVerb = _T("");
	CString strMore = _T("");
	switch(uiFuncType)
	{
		case EMF_ID_CHECK:
			strVerb = _T("ID");
			break;
		case EMF_PN_CHECK:
			strVerb = _T("PN");
			break;
		case EMF_FRIEND_ENTRY:
			strVerb = _T("UP");
			strMore.Format(_T("&hash=%s"), md4str(thePrefs.GetUserHash()));
			break;
		case EMF_FRIEND_REMOVE:
			strVerb = _T("RM");
			break;
		case EMF_FRIEND_LOAD:
			strVerb = _T("FL");
			break;
		default:
			ASSERT(0);
			theApp.QueueDebugLogLineEx(LOG_ERROR, _T("EMF: %hs failed - error: wrong verb"));
			return _T("ER"); //error?
	}

	HINTERNET m_hINet = NULL;
	HINTERNET m_hConnection = NULL;
	HINTERNET m_hData = NULL;
	CString read = _T("");

	try
	{
		m_hINet = InternetOpen(MOD_VERSION, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL); 
		if(!m_hINet) 
			throw GetLastError();

		m_hConnection = InternetConnect(m_hINet, _T("www.emulefuture.eu"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, 0);
		if(!m_hConnection) 
			throw GetLastError();

		const CString& strUserName = thePrefs.GetUserName();
		const CString& strPassWord = thePrefs.GetUserPW();
		CString subpage;
		subpage.Format(_T("emulefuture/modfunctions.php?act=%s&user=%s&pw=%s%s"), strVerb, strUserName, strPassWord, strMore);
		m_hData = HttpOpenRequest(m_hConnection, _T("GET"), subpage, 0, 0, 0, INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | INTERNET_FLAG_PRAGMA_NOCACHE, 0); 
		if(!m_hData) 
			throw GetLastError();

		if(!HttpSendRequest(m_hData, 0, 0, 0, 0))
			throw GetLastError();

		DWORD dwBytesAvail = 0;
		while (InternetQueryDataAvailable(m_hData, &dwBytesAvail, 0, 0))
		{
			BYTE* pBuffer = new BYTE[dwBytesAvail+1];
			DWORD dwBytesRead = 0;
			if(!InternetReadFile(m_hData, pBuffer, dwBytesAvail, &dwBytesRead))
			{
				delete[] pBuffer;
				throw GetLastError();
			}
			if (dwBytesRead == 0)
			{
				delete[] pBuffer;
				break;	//eof
			}

			pBuffer[dwBytesRead] = '\0';
			read.Append(CString(pBuffer));
			delete[] pBuffer;
		}
	}
	catch(DWORD error)
	{
		theApp.QueueDebugLogLineEx(LOG_ERROR, _T("EMF: %hs failed - error: %s"), __FUNCTION__, GetErrorMessage(error));
		read = _T("ER");
	}
	catch(CString err)
	{
		theApp.QueueDebugLogLineEx(LOG_ERROR, _T("EMF: %hs failed - error: %s"), __FUNCTION__, err);
		read = _T("ER");
	}
	catch(...)
	{	
		theApp.QueueDebugLogLineEx(LOG_ERROR, _T("EMF: %hs failed - unknown error"), __FUNCTION__);		
		read = _T("ER");
	}

	//close handles...
	InternetCloseHandle(m_hData); 
	InternetCloseHandle(m_hConnection); 
	InternetCloseHandle(m_hINet);

	return read;
}

bool	DoFriendListEntry(const bool& bAdd)
{	
	//question: should we show some feedback for the friendlist entry?
	if(bAdd)
	{				
		CString succ = CallModFunction(EMF_FRIEND_ENTRY);
		//CString sMsg = _T("");
		if(succ == _T("E"))
		{
			theApp.QueueDebugLogLineEx(LOG_ERROR, GetResString(IDS_EMF_FRIENDLISTADDERROR));
			ASSERT(0); //should never happen!
			return false;
		}
		else
		{
			theApp.QueueDebugLogLineEx(LOG_SUCCESS, GetResString(IDS_EMF_FRIENDLISTADDSUCCESS));
			//success
			return true;
		}
	}
	else //remove
	{				
		CString succ = CallModFunction(EMF_FRIEND_REMOVE);
		//CString sMsg = _T("");
		if(succ == _T("E"))
		{
			theApp.QueueDebugLogLineEx(LOG_WARNING, GetResString(IDS_EMF_FRIENDLISTREMERROR));
			ASSERT(0); //should never happen!
			return false;
		}
		else
		{
			//success
			theApp.QueueDebugLogLineEx(LOG_SUCCESS, GetResString(IDS_EMF_FRIENDLISTREMSUCCESS));
			return true;
		}
	}
}