#include "http_request.h"
#include "http_client.h"
#include "json/json.h"
#include <map>
#include <list>

HttpRequest *HttpRequest::instance_ = nullptr;

HttpRequest *HttpRequest::GetInstance()
{
	if (instance_ == nullptr)
	{
		instance_ = new HttpRequest();
	}
	return instance_;
}

bool ParseJson(std::string message, Json::Value &root)
{
	Json::CharReaderBuilder readerBuilder;

	std::unique_ptr<Json::CharReader> const reader(readerBuilder.newCharReader());

	const char *start_pos = message.c_str();

	std::string err;
	if (!reader->parse(start_pos, start_pos + message.length(), &root, &err))
	{
		return false;
	}

	return true;
}
bool HttpRequest::Init()
{
	return HttpRequest::GetInstance()->Load();
}
bool HttpRequest::LogIn(std::string userid, std::string password, std::string &token, std::string &roomid)
{
	ZgHttpClient client;
	std::string params;

	params = "nickname=" + userid + "&password=" + password + "&uuid=" + "{eae23299-d280-4be2-92a7-8494e18c799b}";

	std::map<std::string, std::string> headers;
	headers["zgl-clienttype"] = "OffcnLiveLR";
	headers["zgl-systemtype"] = "Windows";
	headers["zgl-systemversion"] = "10";
	headers["zgl-clientversion"] = "3.1.1";

	//"https://test-api.live.offcncloud.com/api/v1/users"
	std::string req = HttpRequest::GetInstance()->web_server_url_ + "/api/v1/users";
	std::string response;
	if (!client.Post(req, params, headers, response))
	{
		return false;
	}

	Json::Value root;
	if (!ParseJson(response, root)) return false;

	int code = root["code"].asInt();
	if (code != 0) return false;

	if (!root["data"]) return false;

	Json::Value data = root["data"];
	if (!data["access_token"] || !data["room_id"]) return false;
	
	token = data["access_token"].asString();
	roomid = data["room_id"].asString();

	return true;
}
std::string HttpRequest::GetWebServerUrl()
{
	return HttpRequest::GetInstance()->web_server_url_;
}
bool HttpRequest::Load()
{
	FILE *file = fopen("./config", "r");
	if (file == NULL) return false;

	long fileSize = 0;
	fseek(file, 0, SEEK_END);
	fileSize = ftell(file);
	if (fileSize <= 0) return false;

	char *p = new char[fileSize];
	rewind(file);

	long ret = fread(p, 1, fileSize, file);
	if (ret <= 0)
	{
		delete p;
		fclose(file);
		return false;
	}

	std::string message(p);
	delete p;

	Json::Value root;
	Json::CharReaderBuilder readerBuilder;

	std::unique_ptr<Json::CharReader> const reader(readerBuilder.newCharReader());

	const char *start_pos = message.c_str();

	std::string err;
	if (!reader->parse(start_pos, start_pos + message.length(), &root, &err))
	{
		return false;
	}

	if (root["web_server_url"])
	{
		web_server_url_ = root["web_server_url"].asString();
	}
	else
	{
		return false;
	}
	return true;
}
bool HttpRequest::GetPullUrl(std::string token, std::map<std::string, std::string> &urls)
{
	ZgHttpClient client;

	//std::string url = "http://test-api.live.offcncloud.com/api/v1/pull";
	std::string url = HttpRequest::GetInstance()->web_server_url_ + "/api/v1/pull";

	std::list<std::string> list;
	std::string token1 = std::string("Authorization:bearer ") + token;
	list.push_back(token1.c_str());

	std::string response;
	std::string sError;

	if (!client.Get(url, list, response, sError)) return false;

	Json::Value root;
	if (!ParseJson(response, root)) return false;

	int code = root["code"].asInt();
	if (code != 0) return false;

	if (!root["data"]) return false;

	Json::Value data = root["data"];

	if (!data["rtmp"]) return false;

	std::string rtmp_url = data["rtmp"].asString();
	std::string hls_url = data["hls"].asString();
	std::string vod_url = data["vod"].asString();

	urls["rtmp"] = rtmp_url.c_str();
	urls["hls"] = hls_url.c_str();
	urls["vod"] = vod_url.c_str();

	return true;
}
bool HttpRequest::GetPushUrl(std::string token, std::map<std::string, std::string> &urls)
{
	ZgHttpClient client;

	//std::string url = "http://test-api.live.offcncloud.com/api/v1/push";
	std::string url = HttpRequest::GetInstance()->web_server_url_ + "/api/v1/push";

	std::list<std::string> list;
	std::string token1 = std::string("Authorization:bearer ") + token;
	list.push_back(token1.c_str());

	std::string response;
	std::string sError;

	if (!client.Get(url, list, response, sError)) return false;

	Json::Value root;
	if (!ParseJson(response, root)) return false;

	int code = root["code"].asInt();
	if (code != 0) return false;

	if (!root["data"]) return false;

	Json::Value data = root["data"];

	if (!data["rtmp"]) return false;

	std::string rtmp_url = data["rtmp"].asString();

	urls["rtmp"] = rtmp_url.c_str();

	return true;
}
