#include "CHttpInterceptor.h"
#include "logproc.h"
#include "CCommonTools.h"
#include <QHostAddress>

CHttpInterceptor::CHttpInterceptor()
{
    m_bIsRun = true;
    m_thread = std::thread(std::bind(&CHttpInterceptor::threadProc, this));

}

CHttpInterceptor::~CHttpInterceptor()
{
    m_bIsRun = false;

    m_thread.join();
}

void CHttpInterceptor::init(QString sIp, QString sPort, bool bUseHttps)
{
    bool bIsIp = false;
    QHostAddress test;
    if (test.setAddress(sIp))
    {
        bIsIp = true;
    }

    if(bUseHttps)
    {
        m_sUrl = QString("https://%1:%2").arg(sIp).arg(sPort);
        m_wxUrl = m_sUrl;
        if(!bIsIp)
        {
            m_wxUrl = QString("https://www%1:%2").arg(sIp.right(sIp.length() - sIp.indexOf("."))).arg(sPort);
        }
    }
    else
    {
        m_sUrl = QString("http://%1:%2").arg(sIp).arg(sPort);
        m_wxUrl = m_sUrl;
        if(!bIsIp)
        {
            m_wxUrl = QString("http://www%1:%2").arg(sIp.right(sIp.length() - sIp.indexOf("."))).arg(sPort);
        }
    }
}

void CHttpInterceptor::threadProc()
{
    while(m_bIsRun)
    {
        if(m_mReqPkgList.size() > 0)
        {
            CHttpRequestPackage http_req_pkg;
            {
                std::scoped_lock lock(m_mReqPkgMutex);
                http_req_pkg = m_mReqPkgList.front();
                m_mReqPkgList.pop_front();
            }

            requestProc(http_req_pkg);
        }
        else
        {
            Sleep(100);
        }
    }
}

void CHttpInterceptor::post(CHttpRequestPackage requestPkg)
{
    std::scoped_lock lock(m_mReqPkgMutex);
    requestPkg.nHttpType = HttpType::htPost;
    m_mReqPkgList.push_back(std::move(requestPkg));
}

void CHttpInterceptor::get(CHttpRequestPackage requestPkg)
{
    std::scoped_lock lock(m_mReqPkgMutex);
    requestPkg.nHttpType = HttpType::htGet;
    m_mReqPkgList.push_back(std::move(requestPkg));
}

QString CHttpInterceptor::getHttpUrl() const
{
    return m_wxUrl;
}

void CHttpInterceptor::getUrl(CHttpRequestPackage requestPkg)
{
    std::scoped_lock lock(m_mReqPkgMutex);
    requestPkg.nHttpType = HttpType::htGetUrl;
    m_mReqPkgList.push_back(std::move(requestPkg));
}

void CHttpInterceptor::put(CHttpRequestPackage requestPkg)
{
	std::scoped_lock lock(m_mReqPkgMutex);
	requestPkg.nHttpType = HttpType::htPut;
	m_mReqPkgList.push_back(std::move(requestPkg));
}

void CHttpInterceptor::downLoad(CHttpRequestPackage requestPkg)
{
	std::scoped_lock lock(m_mReqPkgMutex);
	requestPkg.nHttpType = HttpType::htDownload;
	m_mReqPkgList.push_back(std::move(requestPkg));
}

void CHttpInterceptor::initHeads(const CHttpRequestPackage &requestPkg)
{
    if(!requestPkg.sHeadList.isEmpty())
    {
        for(QString sheads : requestPkg.sHeadList)
        {
            QString sKey = sheads.left(sheads.indexOf(","));
            QString sValue = sheads.right(sheads.length() - sheads.indexOf(",") - 1);
            m_httpClient.addHeader(sKey.toStdString(), sValue.toStdString());
        }
    }    
}

bool CHttpInterceptor::doPost(const CHttpRequestPackage &requestPkg, std::string &sResponseStr, int &nCode)
{	
    if(requestPkg.eParamType == HttpParamType::hptBody)
    {
        QString sPostStr = "";
        Json::Value jPost = Json::Value::null;
        if(!requestPkg.sParamList.isEmpty())
        {
            for(QString sParams : requestPkg.sParamList)
            {
                QString sKey = sParams.left(sParams.indexOf(","));
                QString sValue = sParams.right(sParams.length() - sParams.indexOf(",") - 1);
                jPost[sKey.toStdString()] = sValue.toStdString();
                myServerLog() << sParams;
            }

            sPostStr = jPost.toStyledString().c_str();
        }
        else
        {
            sPostStr = "{}";
        }

        std::string sUrl = (m_sUrl + requestPkg.sUri).toStdString();
        if(m_httpClient.post(sUrl, sPostStr.toStdString(), sResponseStr, nCode))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
	else if (requestPkg.eParamType == HttpParamType::hptCustomBody)
	{
		QString sPostStr = "";

		if (requestPkg.sParamList.count() == 1)
		{
			QString sParams = requestPkg.sParamList[0];
			sPostStr = sParams.right(sParams.length() - sParams.indexOf(",") - 1);
		}
		std::string sUrl = (m_sUrl + requestPkg.sUri).toStdString();
		if (m_httpClient.post(sUrl, sPostStr.toStdString(), sResponseStr, nCode))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else if (requestPkg.eParamType == HttpParamType::hptFormdata)
	{
		for (QString sParams : requestPkg.sParamList)
		{
			QString sKey = sParams.left(sParams.indexOf(","));
			QString sValue = sParams.right(sParams.length() - sParams.indexOf(",") - 1);
            if (sKey == "formdataFileType")
			{
                sKey = sValue.left(sValue.indexOf(","));
                sValue = sValue.right(sValue.length() - sValue.indexOf(",") - 1);
				m_httpClient.addFormData(fdt_file, sKey.toStdString(), sValue.toLocal8Bit().data());
				
			}
			else
			{
				m_httpClient.addFormData(fdt_content, sKey.toStdString(), sValue.toStdString());
			}			
		}

        std::string sUrl = requestPkg.bNoHostPrefix ?  requestPkg.sUri.toStdString() : (m_sUrl + requestPkg.sUri).toStdString();
		if (m_httpClient.postFormData(sUrl, sResponseStr, nCode))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
    else
    {

        if(!requestPkg.sParamList.isEmpty())
        {
            for(QString sParams : requestPkg.sParamList)
            {
                QString sKey = sParams.left(sParams.indexOf(","));
                QString sValue = sParams.right(sParams.length() - sParams.indexOf(",") - 1);
                m_httpClient.addParam(sKey.toStdString(), sValue.toStdString());
//				myDebug() << sParams;
            }
        }

        std::string sUrl = (m_sUrl + requestPkg.sUri).toStdString();
        if(m_httpClient.post(sUrl, sResponseStr, nCode))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

bool CHttpInterceptor::doGet(const CHttpRequestPackage &requestPkg, std::string &sResponseStr, int &nCode)
{
    QString sParamStr = "";

    for(QString sParams : requestPkg.sParamList)
    {
        QString sKey = sParams.left(sParams.indexOf(","));
        QString sValue = sParams.right(sParams.length() - sParams.indexOf(",") - 1);
        if(sParamStr.isEmpty())
        {
            sParamStr = sKey + "=" + sValue;
        }
        else
        {
            sParamStr = sParamStr + "&" + sKey + "=" + sValue;
        }

    }

    std::string sUrl = "";
    if(requestPkg.nHttpType ==  HttpType::htGetUrl)
    {
        sUrl = requestPkg.sUri.toStdString();
    }
    else
    {
        if(sParamStr == "")
        {
            sUrl = (m_sUrl + requestPkg.sUri).toStdString();
        }
        else
        {
            sUrl = (m_sUrl + requestPkg.sUri + "?" + sParamStr).toStdString();
        }
    }

    if(m_httpClient.get(sUrl, sResponseStr, nCode))
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool CHttpInterceptor::doPut(const CHttpRequestPackage &requestPkg, std::string &sResponseStr, int &nCode)
{
	QString sParamStr = "";

	for (QString sParams : requestPkg.sParamList)
	{
		QString sKey = sParams.left(sParams.indexOf(","));
		QString sValue = sParams.right(sParams.length() - sParams.indexOf(",") - 1);
		if (sParamStr.isEmpty())
		{
			sParamStr = sKey + "=" + sValue;
		}
		else
		{
			sParamStr = sParamStr + "&" + sKey + "=" + sValue;
		}

	}

	std::string sUrl = "";

	if (sParamStr == "")
	{
		sUrl = (m_sUrl + requestPkg.sUri).toStdString();
	}
	else
	{
		sUrl = (m_sUrl + requestPkg.sUri + "?" + sParamStr).toStdString();
	}
	

	if (m_httpClient.put(sUrl, sResponseStr, nCode))
	{
		return true;
	}
	else
	{
		return false;
	}
}
//下载文件
bool CHttpInterceptor::downLoadFile(std::string uri, std::string sFileName, int &nResCode)
{
    if(m_httpClient.download(uri, sFileName, nResCode))
    {
        return true;
    }
    else
    {
        return false;
    }
}

