#include "stdafx.h"
#include "ClashApi.h"

ClashApi::ClashApi():m_port(0)
{
}

ClashApi::~ClashApi()
{
}

void ClashApi::SetProt(int port)
{
    std::string t;
    t.append("http://127.0.0.1:");
    t.append(std::to_string(port));
    m_api_base_url = t;
}

std::string ClashApi::GetVersion()
{
	cpr::Session   m_cpr_session;
    auto url = m_api_base_url + "/version";
    m_cpr_session.SetUrl(cpr::Url{ url });
    auto res = m_cpr_session.Get();

    THROW_HR_IF(HTTP_E_STATUS_UNEXPECTED, res.status_code != 200);

    return nlohmann::json::parse(res.text).at("version").get<std::string>();
}

ClashConfig ClashApi::GetConfig()
{
	cpr::Session   m_cpr_session;
	auto url = m_api_base_url + "/configs";
	m_cpr_session.SetUrl(cpr::Url{ url });
	auto res = m_cpr_session.Get();
    THROW_HR_IF(HTTP_E_STATUS_UNEXPECTED, res.status_code != 200);
    return  nlohmann::json::parse(res.text).get<ClashConfig>();
}

bool ClashApi::RequestConfigUpdate(std::filesystem::path configPath)
{
	
	try
	{
		cpr::Session   m_cpr_session;
		nlohmann::json j = {
			{"path",Utf16ToUtf8(configPath.wstring())}
		};
		// cpr::Put(cpr::Url{ url }, cpr::Body{ j.dump() });
		auto url = m_api_base_url + "/configs";
	/*	auto url = m_api_base_url + "/configs";
		m_cpr_session.SetUrl(cpr::Url{ url });
		m_cpr_session.SetBody(cpr::Body{ j.dump() });
		auto res = m_cpr_session.Put();*/
		auto ret = cpr::Put(cpr::Url{ url }, cpr::Body{ j.dump() });
		return ret.status_code == 204;
	 
	}
	CATCH_LOG();

    return false;
}

bool ClashApi::UpdateProxyMode(ClashProxyMode mode)
{
	cpr::Session   m_cpr_session;
	nlohmann::json j = {
	{"mode",mode}
	};
	auto url = m_api_base_url + "/configs";
	m_cpr_session.SetUrl(cpr::Url{ url });
	m_cpr_session.SetBody(cpr::Body{ j.dump() });
	auto res = m_cpr_session.Patch();
    return res.status_code == 204;
}

bool ClashApi::UpdateLogLevel(ClashLogLevel level)
{
	cpr::Session   m_cpr_session;
	nlohmann::json j = {
	{"log-level",level}
	};
	auto url = m_api_base_url + "/configs";
	m_cpr_session.SetUrl(cpr::Url{ url });
	m_cpr_session.SetBody(cpr::Body{ j.dump() });
	auto res = m_cpr_session.Patch();
	return res.status_code == 204;
}

bool ClashApi::UpdateAllowLan(bool allow)
{
	cpr::Session   m_cpr_session;
	nlohmann::json j = {
		 {"allow-lan",allow}
	};
	auto url = m_api_base_url + "/configs";
	m_cpr_session.SetUrl(cpr::Url{ url });
	m_cpr_session.SetBody(cpr::Body{ j.dump() });
	auto res = m_cpr_session.Patch();
	return res.status_code == 204;
}

u16milliseconds ClashApi::GetProxyDelay(std::string_view proxyName)
{
	cpr::Session   m_cpr_session;
	std::string path = m_api_base_url + "/proxies/";
	path.append(Utf16ToUtf8(Utf8ToUtf16(proxyName)));
	path.append("/delay"); // "/proxies/\(proxyName.encoded)/delay"

	path.append("?timeout=5000&url=");
	path.append("http://cp.cloudflare.com/generate_204");
	m_cpr_session.SetUrl(cpr::Url{ path });
	auto res = m_cpr_session.Get();
	THROW_HR_IF(HTTP_E_STATUS_UNEXPECTED, res.status_code != 200);
	return u16milliseconds(nlohmann::json::parse(res.text).at("delay").get<uint16_t>());
}

ClashProxies ClashApi::GetProxies()
{
	cpr::Session   m_cpr_session;
	auto url = m_api_base_url + "/proxies";
	m_cpr_session.SetUrl(cpr::Url{ url });
	auto res = m_cpr_session.Get();
	THROW_HR_IF(HTTP_E_STATUS_UNEXPECTED, res.status_code != 200);
	return  nlohmann::json::parse(res.text).get<ClashProxies>();
 
}

bool ClashApi::UpdateProxyGroup(std::string_view group, std::string_view selectProxy)
{
	try
	{
		cpr::Session   m_cpr_session;
		nlohmann::json j = {
			{"name",selectProxy}
		};

		auto url = m_api_base_url + "/proxies/Proxy";
		auto res = cpr::Put(cpr::Url{ url }, cpr::Body{ j.dump() });


		/*std::string path = "/proxies/";
		path.append(group);
		m_cpr_session.SetUrl(cpr::Url{ path });
		m_cpr_session.SetBody(cpr::Body{ j.dump() });
		auto res = m_cpr_session.Put()*/;
		return res.status_code == 204; // HTTP 204 No Content
	}
	catch (...)
	{
		return false;
	}

	return false;
 
}
