#include "MsgHandle.h"
#include <iostream>
#include "../crypto/CryptoTool.h"
//#include <WINSOCK2.H>
//#pragma comment(lib,"ws2_32.lib")
#define MAX_BUFFER_SIZE 10240
MsgHandle::MsgHandle()
{

}


MsgHandle::~MsgHandle()
{

}

bool MsgHandle::parseHeadMsg(const  char* msg, int iLen, MsgHead *head)
{
	if (iLen < sizeof(MsgHead)) return false;
	memcpy_s(head, sizeof(MsgHead), msg, sizeof(MsgHead));
	if (head->szHeaderFlag[0] != 'H' || head->szHeaderFlag[1] != 'S')
		return false;
	return true;
}
string MsgHandle::parseBodyMsg(const string &msg, const MsgHead &head)
{
	string sRet;
	int nBodyLen = head.bodyLen;
	sRet = msg.substr(HEAD_LEN, nBodyLen);
	return sRet;
}
int MsgHandle::encodeMsg(char *pBuf, const string &sBody, const MsgHead &head, const string &sSecretKey)
{
	if (strlen(pBuf) <= 0) return 0;
	MsgHead msgHead = head;
	string sOut = CCryptoTool::RSASignString(PRIVATE_FILE, sBody);
	memcpy_s(msgHead.bodySHA1, 128, sOut.c_str(), sOut.length());
	string sSend;
	sSend = encryptBody(msgHead, sBody, sSecretKey);
	int nBodyLen = sSend.length();
	msgHead.bodyLen = nBodyLen;
	writeMsg(pBuf, msgHead, sSend);
	int nSendLen = nBodyLen + HEAD_LEN;
	return nSendLen;
}
void MsgHandle::writeHeadMsg(char *pBuf, MsgHead &head)
{
	memcpy_s(pBuf, sizeof(MsgHead), &head, sizeof(MsgHead));
}
void MsgHandle::writeBodyMsg(char *pBuf, string &sBody)
{
	memcpy_s(pBuf+HEAD_LEN, sBody.length(), sBody.c_str(), sBody.length());
}
void MsgHandle::writeMsg(char *pBuf, MsgHead &head, string &sBody)
{
	writeHeadMsg(pBuf, head);
	writeBodyMsg(pBuf, sBody);
}

string MsgHandle::decryptBody(const MsgHead &msgHead, const char* sBody, int iLen, string secretKey)
{
	string sRet(sBody);
	if (msgHead.serialNo == 0) {
		// Socket登录初始化 RSA
		if (msgHead.msgType == EN_MSGTYPE_REQ || msgHead.msgType == EN_MSGTYPE_RESP) {
			sRet = CCryptoTool::RSADecryptStringHex(PRIVATE_FILE, sBody,iLen);
		}
	}
	else {
		// 业务请求 AES
		if (msgHead.msgType == EN_MSGTYPE_REQ || msgHead.msgType == EN_MSGTYPE_RESP || msgHead.msgType == EN_MSGTYPE_PUSH) {
			sRet = CCryptoTool::decryptAES(sBody, iLen,secretKey);
		}
	}
	return sRet;
}

string MsgHandle::encryptBody(const MsgHead &msgHead,const string& sBody, string secretKey)
{
	string sRet;
	sRet = sBody;
	if (msgHead.serialNo == 0) {
		// Socket登录初始化 RSA
		if (msgHead.msgType == EN_MSGTYPE_REQ || msgHead.msgType == EN_MSGTYPE_RESP) {
		#ifdef TEST_DEV
			string sFilePub = PUB_FILE_PLAT_TEST;
		#else
			string sFilePub = PUB_FILE_PLAT;
		#endif
			sRet = CCryptoTool::RSAEncryptStringHex(sFilePub.c_str(), sBody);
		}
	}
	else {
		// 业务请求 AES
		if (msgHead.msgType == EN_MSGTYPE_REQ || msgHead.msgType == EN_MSGTYPE_RESP || msgHead.msgType == EN_MSGTYPE_PUSH) {
			if (!secretKey.empty())
				sRet = CCryptoTool::encryptAES(sBody, secretKey);
			else
				cout << "secretKey is empty encryptAES fail" << endl;
		}
	}
	return sRet;
}

bool MsgHandle::signVerify(const MsgHead &msgHead, const string& sBody)
{
	if (msgHead.msgType == EN_MSGTYPE_REQ || msgHead.msgType == EN_MSGTYPE_RESP || msgHead.msgType == EN_MSGTYPE_PUSH) {
		if (strlen(msgHead.bodySHA1)== 0) {
			cout<<"Signature empty.";
			return false;
		}

		try {
			string sSHA1 = string(msgHead.bodySHA1,strlen(msgHead.bodySHA1));
			if (CCryptoTool::RSASignVerifyString(PUB_FILE_PLAT_TEST,sBody, sSHA1)) {
				return true;
			}
			else {
				//cout << "Signature not passed."<<endl;
			}
		}
		catch (...) {
			cout << "Signature verify error" << endl;
		}
	}
	else {
		return true;
	}
	return false;
}

bool MsgHandle::sign(MsgHead &msgHead, string& sBody, string& sOut)
{
	if (msgHead.msgType == EN_MSGTYPE_REQ || msgHead.msgType == EN_MSGTYPE_RESP || msgHead.msgType == EN_MSGTYPE_PUSH) {
		try {
			sOut = CCryptoTool::RSASignString(PRIVATE_FILE, sBody.c_str());
			return true;
		}
		catch (...) {
			cout << "Signature error"<<endl;
		}
	}
	else {
		return true;
	}
	return false;
}

