/***************************************************************************
                   Convert File Control Class  ( ConvertFileControl.cpp )
                -----------------------------------------

	begin      : 2013/03/20
	copyright  : (C) 2013 Solbox Inc.
	author     : Development 1 Team
					- 2013/03/20 - 1st dadamin
	email      : dev1@solbox.com
	version    : 3.2.0

	CopyRight(C) 2005 Solbox Inc. All Rights reserved.
	Redistribution and use in source and binary forms, with or with out
	modification, are not permitted in outside of Solbox Inc.
***************************************************************************/
#include "rc_mngd.h"
#include "Convert.h"
#include "ConvertFileControl.h"
#include "Logger.h"
#include "UtilFn.h"
#include "Protocol.h"

#define  STR_10MB	"10"

CConvertFileControl::CConvertFileControl(string subkey /* = "" */)
	: m_subkey(subkey)
{

}

CConvertFileControl::~CConvertFileControl()
{

}

int CConvertFileControl::ToJobData(int nServiceType, void* pFrom, void *pTo)
{
	int r = 0;
	CJobDataMap *pMap = reinterpret_cast<CJobDataMap *>(pTo);

	switch(nServiceType)
	{
	case CServiceInfo::ETC:
		{			
			if(m_subkey.compare(JOB_FILE_CTL_GET_HASH_10MB) == 0)
			{
				EtcReqBodyMD5_10MB *pBody = (EtcReqBodyMD5_10MB*)pFrom;

				vector<string> ids;
				StringSplit(pBody->userid, ID_DELIMITER, ids);

				if( ids.size() != 2 )
				{
					r = JOB_ERR_CONVERT;
					LOG(LERR, "Unknown type ID.[%s]", pBody->userid);
					break;
				}

				pMap->insert(CJobDataPair(KEY_SP_USER_ID, ids[1]));
				pMap->insert(CJobDataPair(KEY_SP_SVC_ID, ids[0]));

				pMap->insert(CJobDataPair(KEY_REQ_URI, pBody->uri));
				pMap->insert(CJobDataPair(KEY_GET_CONTENT_LENGTH, pBody->filesize));
				
				pMap->insert(CJobDataPair(KEY_REQ_HASH_CHECK_SIZE, STR_10MB)); // 10MB
				
			}
			else 
			{
				r = JOB_ERR_CONVERT;
				LOG(LERR, "Service does not support the conversion.");
				break;
			}
			pMap->insert(CJobDataPair(KEY_JOB_TYPE, JOB_FILE_CTL));
			pMap->insert(CJobDataPair(KEY_JOBSUB_TYPE, m_subkey));



			r = pMap->size();
		}
		break;
	case CServiceInfo::XML:
		{
			try
			{
				const xmlpp::Node* node = const_cast<xmlpp::Node*>((xmlpp::Node*)pFrom);

				pMap->insert(CJobDataPair(KEY_JOB_TYPE, JOB_FILE_CTL));
				pMap->insert(CJobDataPair(KEY_JOBSUB_TYPE, m_subkey));

				string volumeid = GetElementValue(node, XML_STR_VOLUME_ID);
				if (volumeid.size())
				{
					pMap->insert(CJobDataPair(KEY_VOLUME_ID, GetElementValue(node, XML_STR_VOLUME_ID)));

					vector<string> ids;
					StringSplit(volumeid, ID_DELIMITER, ids);
					if (ids.size() == 2)
					{
						pMap->insert(CJobDataPair(KEY_SP_SVC_ID, ids[0]));
						pMap->insert(CJobDataPair(KEY_SP_USER_ID, ids[1]));
					}
				}
				else
				{
					r = JOB_ERR_CONVERT;
					LOG(LERR, "Service does not support the conversion.");
					break;
				}

				pMap->insert(CJobDataPair(KEY_SP_USER_PASSWORD, GetElementValue(node, XML_STR_USER_PASSWORD)));
				pMap->insert(CJobDataPair(KEY_REQ_URI, GetElementValue(node, XML_STR_FILE_URI)));
				
				r = pMap->size();
			}
			catch (const std::exception& ex)
			{
				LOG(LERR, "Exception caught: %s", ex.what());
			}

		}
		break;
	case CServiceInfo::SDK:
	default:
		r = JOB_ERR_CONVERT;
		LOG(LERR, "Service does not support the conversion.");
		break;
	}		

	return r;
}

void* CConvertFileControl::ToClientData(int nServiceType, int nEnd, void* pFrom, int & outlen)
{
	void *r = NULL;
	CJobDataMap *pMap = reinterpret_cast<CJobDataMap *>(pFrom);

	switch(nServiceType)
	{
	case CServiceInfo::ETC:
		{
			outlen = 0;
			if(m_subkey.compare(JOB_FILE_CTL_GET_HASH_10MB) == 0)
			{
				string hash = GetJobMapValue(pFrom, KEY_RES_FILE_FRONT_10M_MD5);
				string uri = GetJobMapValue(pFrom, KEY_REQ_URI);
				string svcid = GetJobMapValue(pFrom, KEY_SP_SVC_ID);
				string userid = GetJobMapValue(pFrom, KEY_SP_USER_ID);

				if(!hash.empty())
				{
					BYTE * t = NULL;
					t = new BYTE [sizeof(EtcResBodyMD5_10MB)];
					if(t)
					{
						EtcResBodyMD5_10MB body;
						snprintf(body.userid, MAX_SIZE_OF_USERID, "%s%s%s",
								svcid.c_str(), ID_DELIMITER, userid.c_str());
						strcpy(body.uri, uri.c_str());
						strcpy(body.hash, hash.c_str());

						outlen = sizeof(body);
						memcpy(t, &body, outlen);
						
						r = (void *)t;
					}
					else
					{
						outlen = -1;
						LOG(LERR, "Memory allocation failure.");
					}
				}
			}
			else 
			{
				outlen = -1;
				LOG(LERR, "Service does not support the conversion.");
				break;
			}
		}
		break;
	case CServiceInfo::XML:
		{
			string strtype = XML_STR_JOB_TYPE;
			string val = GetJobMapValue(pFrom, KEY_RES_XML_JOB_TYPE);
			string strlist = XML_STR_JOB_TYPE_LIST;
			string val2 = GetJobMapValue(pFrom, KEY_RES_XML_JOB_TYPE_List);

			string svcid = GetJobMapValue(pFrom, KEY_SP_SVC_ID);
			string userid = GetJobMapValue(pFrom, KEY_SP_USER_ID);

			string volumeid = svcid + "@" + userid;
			string rValue = ((nEnd == JOB_SUCCESS) ? JOX_RESULT_OK : JOX_RESULT_FAIL);
			ostringstream rcode;
			rcode << nEnd;


			try
			{
				xmlpp::Document document;
				// root 
				xmlpp::Element* nodeRoot = document.create_root_node(XML_STR_ROOT, "", "");
				// Response
				xmlpp::Element* nodeResponses = nodeRoot->add_child(XML_STR_JOB);

				nodeResponses->set_attribute(strtype, val);
				nodeResponses->set_attribute(strlist, val2);

				SetElementValue(nodeResponses, XML_STR_VOLUME_ID, volumeid);
				SetElementValue(nodeResponses, XML_STR_RESULT, rValue);
				SetElementValue(nodeResponses, XML_STR_RESULT_CODE, rcode.str());

				if (nEnd == JOB_SUCCESS)
				{
					SetElementValue(nodeResponses, XML_STR_FILE_URI, GetJobMapValue(pFrom, KEY_REQ_URI));

					string f10md5 = GetJobMapValue(pFrom, KEY_RES_FILE_FRONT_10M_MD5);
					string filelan = GetJobMapValue(pFrom, KEY_RES_FILE_SIZE);
					string szTotoMd5 = GetJobMapValue(pFrom, KEY_RES_FILE_TOTO_MD5);
					string szChecksum = GetJobMapValue(pFrom, KEY_RES_FILE_TOTO_CHECKSUM);
					string szDnaCheckKey = GetJobMapValue(pFrom, KEY_RES_FILE_TOTO_DNAKEY);
					
					if (val2.find(XML_STR_FILE_MKDIR) == string::npos)
					{
						SetElementValue(nodeResponses, XML_STR_FILE_SIZE, filelan);
					}					

					if (val2.find(XML_STR_FILE_FRONT_10M_MD5) != string::npos)
					{
						SetElementValue(nodeResponses, XML_STR_FILE_10M_MD5, f10md5);
					}
					else if (val2.find(XML_STR_FILE_TOTO_EXTRACT_WITHPLATFORM) != string::npos)
					{
						SetElementValue(nodeResponses, XML_STR_TOTO_MD5, szTotoMd5);
						SetElementValue(nodeResponses, XML_STR_TOTO_FILECHECKSUM, szChecksum);
						SetElementValue(nodeResponses, XML_STR_TOTO_DNACHKKEY, szDnaCheckKey);
					}
					else
					{
						// noting
					}
				}

				string szData = document.write_to_string();

				BYTE *t = NULL;
				outlen = szData.size();
				t = new BYTE[outlen + 1];

				if (t)
				{
					memcpy(t, szData.c_str(), outlen);
					t[outlen] = '\0';
					r = (void*)t;
					LOG(LDBG, "CConvertServiceChange ToClientData(XML) : %s, %d", (char *)r, outlen);
				}
				else
				{
					outlen = -1;
					LOG(LERR, "Memory allocation error.[%d]", errno);
				}
			}
			catch (const std::exception& ex)
			{
				outlen = -1;
				LOG(LERR, "Exception caught: %s", ex.what());
			}
		}
		break;
	case CServiceInfo::SDK:
	default:
		outlen = -1;
		LOG(LERR, "Service does not support the conversion.");
		break;
	}

	return r;
}
