/***************************************************************************
                   Convert Request Service Move Class  ( ConvertReqServiceMove.cpp )
                -----------------------------------------

	begin      : 2013/03/18
	copyright  : (C) 2013 Solbox Inc.
	author     : Development 1 Team
					- 2013/03/18 - 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 "ConvertReqServiceMove.h"
#include "Logger.h"
#include "UtilFn.h"

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

}

CConvertReqSvcMove::~CConvertReqSvcMove()
{

}

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

	switch(nServiceType)
	{
	case CServiceInfo::XML:
		{
			// move request
			if (m_subkey.compare(JOB_SERVICE_MOVE_REQUEST) == 0 || 
				m_subkey.compare(JOB_SERVICE_MOVE_COMPLETE) == 0)
			{
				try
				{
					const xmlpp::Node* node = const_cast<xmlpp::Node*>((xmlpp::Node*)pFrom);
										
					pMap->insert(CJobDataPair(KEY_VOLUME_ID, GetElementValue(node, XML_STR_VOLUME_ID)));
					pMap->insert(CJobDataPair(KEY_VOLUME_SEQ, GetElementValue(node, XML_STR_VOLUME_SEQ)));
					pMap->insert(CJobDataPair(KEY_RESP_RESULT, GetElementValue(node, XML_STR_RESULT)));
					pMap->insert(CJobDataPair(KEY_RESP_RESULT_CODE, GetElementValue(node, XML_STR_RESULT_CODE)));

					r = pMap->size();
				}
				catch (const std::exception& ex)
				{
					LOG(LERR, "Exception caught: %s", ex.what());
				}
			}
			else
			{
				r = JOB_ERR_CONVERT;
				LOG(LERR, "Service does not support the conversion.");
			}
		}		
		break;
	case CServiceInfo::SDK:
	case CServiceInfo::ETC:
	default:
		r = JOB_ERR_CONVERT;
		LOG(LERR, "Service does not support the conversion.");
		break;
	}		

	return r;
}

string CConvertReqSvcMove::MakeMoveRequestXML(void* pData)
{
	string r;
	CJobDataMap *pMap = reinterpret_cast<CJobDataMap *>(pData);

	const char *_f[] =
	{
		// sql << "u.sp_user_id,u.sp_user_seq, u.sp_user_password,";
		KEY_SP_USER_ID, KEY_SP_USER_SEQ, KEY_SP_USER_PASSWORD,
		// sql << "s.sp_svc_id, s.sp_svc_tran_id,s.max_str_size,s.sp_svc_begin_date,s.sp_svc_end_date,";
		KEY_SP_SVC_ID, KEY_SP_SVC_TRAN_ID,
		KEY_MAX_STR_SIZE, KEY_SP_SVC_BEGIN_DATE, KEY_SP_SVC_END_DATE,
		// sql << "s.initial_vector,s.private_key,";
		KEY_INITIAL_VECTOR, KEY_PRIVATE_KEY,
		// sql << "s.replication_count,s.uri_ignore_case,s.cal_used_depth,s.del_file_keep_time,";
		KEY_REPLICATION_COUNT, KEY_URI_IGNORE_CASE, KEY_CAL_USED_DEPTH, KEY_DEL_FILE_KEEP_TIME,
		// sql << "s.validate_sp_session_id_yn,";
		KEY_VALIDATE_SP_SESSION_ID_YN,
		// sql << "v.mode,";
		KEY_REQ_AUTH_MODE,
		// sql << "v.auth_server,v.auth_path,v.auth_port,v.auth_timeout,";
		KEY_AUTH_SERVER, KEY_AUTH_PATH, KEY_AUTH_PORT, KEY_AUTH_TIMEOUT,
		// sql << "v.bill_server,v.bill_path,v.bill_port,v.bill_timeout,";
		KEY_BILL_SERVER, KEY_BILL_PATH, KEY_BILL_PORT, KEY_BILL_TIMEOUT,
		// sql << "s.bandwidth_ctrl_yn,";
		KEY_BANDWIDTH_CTRL_YN,
		// sql << "b.volume_bandwidth_limit,";
		KEY_VOLUME_BANDWIDTH_LIMIT,
		// sql << "r.host_name ";
		KEY_HOST_NAME,
		KEY_LINK_MASTER_YN,
		KEY_LINK_SP_SVC_TRAN_ID, KEY_LINK_RCTS,
		0
	};

	const char *o[] =
	{
		// sql << "u.sp_user_id,u.sp_user_seq, u.sp_user_password,";
		XML_STR_USER_ID, XML_STR_USER_SEQ, XML_STR_USER_PASSWORD,
		// sql << "s.sp_svc_id, s.sp_svc_tran_id,s.max_str_size,s.sp_svc_begin_date,s.sp_svc_end_date,";
		XML_STR_SVC_ID, XML_STR_SVC_SEQ,
		XML_STR_SVC_STGSIZE, XML_STR_SVC_START_DATE, XML_STR_SVC_END_DATE,
		// sql << "s.initial_vector,s.private_key,";
		XML_STR_SVC_AUTHSTRING, XML_STR_SVC_PRIVATEKEY,
		// sql << "s.replication_count,s.uri_ignore_case,s.cal_used_depth,s.del_file_keep_time,";
		XML_STR_SVC_REPLICA, XML_STR_SVC_URIIGNORECASE, XML_STR_SVC_USEDSIZECALCDEPTH, XML_STR_SVC_DELFILEKEEPTIME,
		// sql << "s.validate_sp_session_id_yn,";
		XML_STR_CUSTOMAUTH_YN,
		// sql << "v.mode,";
		XML_STR_CUSTOMAUTH_MODE,
		// sql << "v.auth_server,v.auth_path,v.auth_port,v.auth_timeout,";
		XML_STR_AUTHSERVER, XML_STR_AUTHPATH, XML_STR_AUTHPORT, XML_STR_AUTHTIMEOUT,
		// sql << "v.bill_server,v.bill_path,v.bill_port,v.bill_timeout,";
		XML_STR_BILLSERVER, XML_STR_BILLPATH, XML_STR_BILLPORT, XML_STR_BILLTIMEOUT,
		// sql << "s.bandwidth_ctrl_yn,";
		XML_STR_TRAFFICLIMIT_YN,
		// sql << "b.volume_bandwidth_limit,";
		XML_STR_TRAFFICLIMIT,
		// sql << "r.host_name ";
		XML_STR_SVC_DOMAIN,
		XML_STR_LINK_MASTER_YN,
		XML_STR_LINK_SERVICE_SEQ, XML_STR_LINK_RCTS,
		0
	};

	try
	{

		xmlpp::Document document;
		// root 
		xmlpp::Element* nodeRoot = document.create_root_node(XML_STR_ROOT, "", "");

		xmlpp::Element* nodeRequest = nodeRoot->add_child(XML_STR_JOB);

		nodeRequest->set_attribute(XML_STR_JOB_TYPE, XML_STR_TYPE_MOVE_N_SYNC);

		for (unsigned int i = 0; _f[i] != NULL; ++i)
		{
			SetElementValue(nodeRequest, o[i], GetJobMapValue(pData, _f[i]));
		}

		r = document.write_to_string();
	}
	catch (const std::exception& ex)
	{
		LOG(LERR, "Exception caught: %s", ex.what());
	}

	return r;
}

string CConvertReqSvcMove::MakeMoveCompleteXML(void* pData)
{
	string r;
	CJobDataMap *pMap = reinterpret_cast<CJobDataMap *>(pData);

	try
	{

		xmlpp::Document document;
		// root 
		xmlpp::Element* nodeRoot = document.create_root_node(XML_STR_ROOT, "", "");

		xmlpp::Element* nodeRequest = nodeRoot->add_child(XML_STR_JOB);

		nodeRequest->set_attribute(XML_STR_JOB_TYPE, XML_STR_TYPE_CHANGE);
		nodeRequest->set_attribute(XML_STR_JOB_TYPE_LIST, XML_STR_SVC_SYNC_LINK);

		SetElementValue(nodeRequest, XML_STR_VOLUME_SEQ, GetJobMapValue(pData, KEY_VOLUME_SEQ));
		SetElementValue(nodeRequest, XML_STR_SELF_RCTS, GetJobMapValue(pData, KEY_SELF_RCTS));
		SetElementValue(nodeRequest, XML_STR_LINK_MASTER_YN, GetJobMapValue(pData, KEY_LINK_MASTER_YN));
		SetElementValue(nodeRequest, XML_STR_LINK_USER_SEQ, GetJobMapValue(pData, KEY_LINK_USER_SEQ));
		SetElementValue(nodeRequest, XML_STR_LINK_SERVICE_SEQ, GetJobMapValue(pData, KEY_LINK_SP_SVC_TRAN_ID));
		SetElementValue(nodeRequest, XML_STR_LINK_RCTS, GetJobMapValue(pData, KEY_LINK_RCTS));
		SetElementValue(nodeRequest, XML_STR_LINK_CODE, GetJobMapValue(pData, KEY_REQ_LINK_CODE));
		SetElementValue(nodeRequest, XML_STR_LINK_ONE_WAY, GetJobMapValue(pData, KEY_REQ_LINK_ONE_WAY));

		r = document.write_to_string();
	}
	catch (const std::exception& ex)
	{
		LOG(LERR, "Exception caught: %s", ex.what());
	}


	return r;
}

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

	switch(nServiceType)
	{	
	case CServiceInfo::XML:
		{
			string szData;


			if (m_subkey.compare(JOB_SERVICE_MOVE_REQUEST) == 0)
			{
				szData = MakeMoveRequestXML(pFrom);
			}
			else if (m_subkey.compare(JOB_SERVICE_MOVE_COMPLETE) == 0)
			{
				szData = MakeMoveCompleteXML(pFrom);
			}
			else
			{
				outlen = -1;
				LOG(LERR, "Service does not support the conversion.");
			}

			if (szData.size())
			{
				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, "CConvertReqSvcMove ToClientData(XML) : %s, %d", (char *)r, outlen);
				}
				else
				{
					outlen = -1;
					LOG(LERR, "Memory allocation error.[%d]", errno);
				}
			}
		}
		break;
	case CServiceInfo::SDK:
	case CServiceInfo::ETC:
	default:
		outlen = -1;
		LOG(LERR, "Service does not support the conversion.");
		break;
	}

	return r;
}
