#include "stdafx.h"
#include "CManageNetWork.h"
#include "CNetWork.h"
#include "CApp.h"
#include "FileOperate.h"
#include <nlohmann/json.hpp>

CManageNetWork* SSingleton<CManageNetWork>::ms_Singleton = NULL;


CManageNetWork::CManageNetWork() : m_base_curl(nullptr), m_Asyntask(4)
{
}

CManageNetWork::~CManageNetWork()
{
	if (m_base_curl)
	{
		delete m_base_curl;
		m_base_curl = nullptr;
	}
}

void CManageNetWork::init()
{


	SNotifyCenter::getSingleton().addEvent(EVENTID(EventLogin));
	SNotifyCenter::getSingleton().addEvent(EVENTID(EventDoWNload));
	SNotifyCenter::getSingleton().addEvent(EVENTID(EventNodeList));
	SNotifyCenter::getSingleton().addEvent(EVENTID(EventVerions));
	SNotifyCenter::getSingleton().addEvent(EVENTID(EventSysconfig));
	SNotifyCenter::getSingleton().addEvent(EVENTID(EventAUTH));


	if (!m_base_curl)
	{
		m_base_curl = new CNetWork();
		//m_base_curl.Attach(new CNetWork());
	}

	LoadFileToData();
}

void CManageNetWork::Login(LPCSTR username, LPCSTR password)
{
	if (!m_base_curl)
	{
		return;
	}

	this->m_username = username;
	this->m_password = password;

	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_login, this, (LPARAM)m_base_curl);

	
	 
}

void CManageNetWork::SetUrl(LPCSTR url)
{
	if (!m_base_curl)
	{
		return;
	}

	m_base_curl->SetUrl(url);
}

SStringA CManageNetWork::GetUsername()
{
	return m_username;
}

SStringA CManageNetWork::GetPassWord()
{
	return m_password;
}

void CManageNetWork::DonloadConfg()
{
	if (!m_base_curl)
	{
		return;
	}
	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Dowlon_Config, this, (LPARAM)m_base_curl);
}

void CManageNetWork::GetNodeList()
{
	if (!m_base_curl)
	{
		return;
	}
	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Node_Config, this, (LPARAM)m_base_curl);
}

void CManageNetWork::GetVersion()
{
	if (!m_base_curl)
	{
		return;
	}

	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Version_Config, this, (LPARAM)m_base_curl);

}

void CManageNetWork::GetSysConfig()
{
	if (!m_base_curl)
	{
		return;
	}
	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Sys_Config, this, (LPARAM)m_base_curl);
}

void CManageNetWork::Auth()
{
	if (!m_base_curl)
	{
		return;
	}
	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Auth, this, (LPARAM)m_base_curl);
}

void CManageNetWork::Reg(LPCSTR username, LPCSTR password)
{
	if (!m_base_curl)
	{
		return;
	}
	
	this->m_username = username;
	this->m_password = password;

	m_Asyntask.AddTask(&CManageNetWork::ThreadFun_Reg, this, (LPARAM)m_base_curl);
}

void CManageNetWork::SetUrlList(std::vector<ServerListUrl> data)
{
	if (!m_base_curl)
	{
		return;
	}

	m_base_curl->SetUrlArray(data);
}

void CManageNetWork::ThreadFun_login(LPARAM lParam)
{
	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
	int code = 200;
	SStringW msg = L"";
	std::string data;

	HTTPRET httpstatus = m_base_curl->GetSysConfigFromUser(this->m_username, this->m_password, data);
	if (httpstatus == HTTPRET::http_user_expired_at)
	{
		code = -2;
		msg = m_base_curl->GetLastErrorW();

	}
	else if (httpstatus == HTTPRET::http_user_transfer_enable) {
		code = -3;
		msg = m_base_curl->GetLastErrorW();
	}
	else if (httpstatus == HTTPRET::http_f) {
		code = 0;
		msg = m_base_curl->GetLastErrorW();
	}

	if (!data.empty())
	{
		if (!CApp::getSingletonPtr()->GetSysconfig()->Inti(data)) {

		}
		
	}

	data.empty();

	httpstatus = m_base_curl->PostLogin(this->m_username, this->m_password, data);
	if (httpstatus == HTTPRET::http_user_expired_at)
	{
		code = -2;
		msg = m_base_curl->GetLastErrorW();

	}
	else if(httpstatus == HTTPRET::http_user_transfer_enable){
		code = -3;
		msg = m_base_curl->GetLastErrorW();
	} 
	else if (httpstatus == HTTPRET::http_f) {
		code = 0;
		msg = m_base_curl->GetLastErrorW();
	}

	if (!data.empty())
	{
		if (!CApp::getSingletonPtr()->GetUserinfo()->Init(data))
		{
			code = -1;
			msg = CApp::getSingletonPtr()->GetUserinfo()->GetLastErrorW();
		}
	}


	DataToFile();

	EventLogin* pEvt = new EventLogin(nullptr);
	pEvt->status = code;
	pEvt->msg = msg;
	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
	pEvt->Release();
}

void CManageNetWork::ThreadFun_Dowlon_Config(LPARAM lParam)
{
	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
	int code = 200;
	SStringW msg = L"";
	std::string data;
	if (!m_base_curl->Download(CApp::getSingletonPtr()->GetUserinfo()->clash_config)) {
		code = 0;
		msg = L"下载文件失败";
		 
	}
	EventDoWNload* pEvt = new EventDoWNload(nullptr);
	pEvt->status = code;
	pEvt->msg = msg;
	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
	pEvt->Release();
}


void CManageNetWork::ThreadFun_Sys_Config(LPARAM lParam)
{
	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
	int code = 200;
	SStringW msg = L"";
	std::string data;
	//if (m_base_curl->Version(data) == HTTPRET::http_f) {
	//	code = 0;
	//	msg = m_base_curl->GetLastErrorW();
	//}
	HTTPRET httpstatus = m_base_curl->GetSysConfig(data);
	if (httpstatus == HTTPRET::http_user_expired_at)
	{
		code = -2;
		msg = m_base_curl->GetLastErrorW();

	}
	else if (httpstatus == HTTPRET::http_user_transfer_enable) {
		code = -3;
		msg = m_base_curl->GetLastErrorW();
	}
	else if (httpstatus == HTTPRET::http_f) {
		code = 0;
		msg = m_base_curl->GetLastErrorW();
	}
	if (!data.empty())
	{
		if (!CApp::getSingletonPtr()->GetSysconfig()->Inti(data))
		{
			code = -1;
			msg = CApp::getSingletonPtr()->GetSysconfig()->GetLastErrorW();
		}

	}
	EventSysconfig* pEvt = new EventSysconfig(nullptr);
	pEvt->status = code;
	pEvt->msg = msg;
	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
	pEvt->Release();
}


void CManageNetWork::ThreadFun_Version_Config(LPARAM lParam)
{
	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
	int code = 200;
	SStringW msg = L"有新版本,点我升级";
	std::string data;
	if (m_base_curl->Version(data) == HTTPRET::http_f) {
		code = 0;
		msg = m_base_curl->GetLastErrorW();
	}
	if (!data.empty())
	{
		if (!CApp::getSingletonPtr()->GetVerinfo()->Inti(data))
		{
			code = -1;
			msg = CApp::getSingletonPtr()->GetVerinfo()->GetLastErrorW();
		}
		 
	}
	EventVerions* pEvt = new EventVerions(nullptr);
	pEvt->status = code;
	pEvt->msg = msg;
	pEvt->versionupdate = CApp::getSingletonPtr()->GetVerinfo()->versionupdate;
	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
	pEvt->Release();
}

void CManageNetWork::ThreadFun_Node_Config(LPARAM lParam)
{
	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
	int code = 200;
	SStringW msg = L"";
	std::string data;
	int count = 0;
	do 
	{
		data = "";

		HTTPRET httpstatus = m_base_curl->GetServerNode(data);
		if (httpstatus == HTTPRET::http_f) {
			code = 0;
			msg = m_base_curl->GetLastErrorW();
		}

		if (m_base_curl->GetHttpStatus() == 401)
		{
			if (count >= 3)
			{
				code = m_base_curl->GetHttpStatus();
				msg = L"鉴权失败,需要重新登录";
				break;
			}
			httpstatus = m_base_curl->PostLogin(this->m_username, this->m_password, data);
			if (httpstatus == HTTPRET::http_f) {
				code = m_base_curl->GetHttpStatus();
				msg = m_base_curl->GetLastErrorW();
				count++;
			}
			else {
				if (!CApp::getSingletonPtr()->GetUserinfo()->Init(data))
				{
					code = -1;
					msg = CApp::getSingletonPtr()->GetServerList()->GetLastErrorW();
				}
				
				continue;
			}
			
		}
		else {
			if (!data.empty())
			{
				if (!CApp::getSingletonPtr()->GetServerList()->Init(data))
				{
					code = -1;
					msg = CApp::getSingletonPtr()->GetServerList()->GetLastErrorW();
				}

				break;
			}
		}
 
	


	} while (m_base_curl);


	EventNodeList* pEvt = new EventNodeList(nullptr);
	pEvt->status = code;
	pEvt->msg = msg;
	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
	pEvt->Release();
}

void CManageNetWork::ThreadFun_Auth(LPARAM lParam)
{
	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
	int code = 200;
	SStringW msg = L"";
	std::string data;
	int count = 0;
	do 
	{
		HTTPRET http_status = m_base_curl->Auth(data);
		if (http_status == HTTPRET::http_f) {
			code = 0;
			msg = m_base_curl->GetLastErrorW();
			break;
		}
		auto status = CApp::getSingletonPtr()->GetUserinfo()->authInit(data);
		if (status != -1) {
			code = status;
			msg = CApp::getSingletonPtr()->GetUserinfo()->GetLastErrorW();
			break;
		}


		/*else if (http_status == HTTPRET::http_user_expired_at) {

		}
		else if (http_status == HTTPRET::http_user_transfer_enable)
		{
			code = 0;
			msg = m_base_curl->GetLastErrorW();
			break;
		}*/

		//重新鉴权
		if (m_base_curl->GetHttpStatus() == 401)
		{
			if (count >= 3)
			{
				code = m_base_curl->GetHttpStatus();
				msg = L"鉴权失败,需要重新登录";
				break;
			}
			http_status = m_base_curl->PostLogin(this->m_username, this->m_password, data);
			if (http_status == HTTPRET::http_f) {
				code = m_base_curl->GetHttpStatus();
				msg = m_base_curl->GetLastErrorW();
				count++;
			}
			else {
				if (!CApp::getSingletonPtr()->GetUserinfo()->Init(data))
				{
					code = -1;
					msg = CApp::getSingletonPtr()->GetServerList()->GetLastErrorW();
				}

				continue;
			}

		}
		else {
			code == 200;
			break;
		}

	} while (m_base_curl);
	
	EventAUTH* pEvt = new EventAUTH(nullptr);
	pEvt->status = code;
	pEvt->msg = msg;
	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
	pEvt->Release();
}

void CManageNetWork::ThreadFun_Reg(LPARAM lParam)
{
	IBaseCurl* lpAsyncParam = reinterpret_cast<IBaseCurl*>(lParam);
	int code = 200;
	SStringW msg = L"";
	std::string data;

	HTTPRET httpstatus = m_base_curl->GetSysConfigFromUser(this->m_username, this->m_password, data);
	if (httpstatus == HTTPRET::http_user_expired_at)
	{
		code = -2;
		msg = m_base_curl->GetLastErrorW();

	}
	else if (httpstatus == HTTPRET::http_user_transfer_enable) {
		code = -3;
		msg = m_base_curl->GetLastErrorW();
	}
	else if (httpstatus == HTTPRET::http_f) {
		code = 0;
		msg = m_base_curl->GetLastErrorW();
	}

	if (!data.empty())
	{
		if (!CApp::getSingletonPtr()->GetSysconfig()->Inti(data)) {

		}

	}

	data.empty();

	httpstatus = m_base_curl->PostReg(this->m_username, this->m_password, data);
	if (httpstatus == HTTPRET::http_user_expired_at)
	{
		code = -2;
		msg = m_base_curl->GetLastErrorW();

	}
	else if (httpstatus == HTTPRET::http_user_transfer_enable) {
		code = -3;
		msg = m_base_curl->GetLastErrorW();
	}
	else if (httpstatus == HTTPRET::http_f) {
		code = 0;
		msg = m_base_curl->GetLastErrorW();
	}

	if (!data.empty())
	{
		if (!CApp::getSingletonPtr()->GetUserinfo()->Init(data))
		{
			code = -1;
			msg = CApp::getSingletonPtr()->GetUserinfo()->GetLastErrorW();
		}
	}


	DataToFile();

	EventLogin* pEvt = new EventLogin(nullptr);
	pEvt->status = code;
	pEvt->msg = msg;
	SNotifyCenter::getSingleton().FireEventAsync(pEvt);
	pEvt->Release();
}

void CManageNetWork::LoadFileToData() {

	try
	{
		FileOperate f;
		SStringA   paht;

		paht.Format("%s\\%s", CApp::getSingletonPtr()->GetDataPath().string().c_str(), S_CW2A(DSPROXY_CONFIG_NAME, CP_UTF8));

		if (f.open(paht.GetBuffer(0), std::fstream::in | std::fstream::out | std::fstream::app)) {
			std::string data = f.readAll();
			if (data.empty())
			{
				return;
			}
			nlohmann::json j3 = nlohmann::json::parse(data.begin(), data.end());
			this->m_username = j3["username"].get<std::string>().c_str();
			this->m_password = j3["password"].get<std::string>().c_str();

		}
		f.close();
	}
	CATCH_LOG();
	
}

void CManageNetWork::DataToFile()
{
	try
	{
		nlohmann::json j3;
		j3["username"] = this->m_username;
		j3["password"] = this->m_password;

		auto str = j3.dump(4);

		FileOperate f;
		SStringA   paht;

		paht.Format("%s\\%s", CApp::getSingletonPtr()->GetDataPath().string().c_str(), S_CW2A(DSPROXY_CONFIG_NAME, CP_UTF8));


		f.create(paht.GetBuffer(0));

		if (f.open(paht.GetBuffer(0), std::fstream::in | std::fstream::out | std::fstream::app)) {
			f.write(str);
		}

		f.close();
	}
	CATCH_LOG();

}