/***************************************************************************
                   Convert Base Class  ( Convert.cpp )
                -----------------------------------------

	begin      : 2013/02/28
	copyright  : (C) 2013 Solbox Inc.
	author     : Development 1 Team
					- 2013/02/28 - 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 "Logger.h"
#include "Protocol.h"
#include "ConvertServiceOpen.h"
#include "ConvertServiceChange.h"
#include "ConvertVolumeInfo.h"
#include "ConvertAnonymousDir.h"
#include "ConvertFileControl.h"

// Convert base class
CConvert::CConvert()
{

}

CConvert::~CConvert()
{

}

string CConvert::GetElementValue(const xmlpp::Node* node, string elmentName)
{
	string ret;

	try
	{
		xmlpp::Node* n;

		if( elmentName.empty() )
		{
			n = const_cast<xmlpp::Node*>(node);
		}
		else
		{
			n = node->get_children(elmentName).front();

			if( n == NULL || node->get_children(elmentName).size() == 0 )
				return ret;	
		}


		const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(n);
		if(nodeElement)
		{
			const xmlpp::TextNode*  nodetext = nodeElement->get_child_text();
			if(nodetext)
			{
				ret = nodetext->get_content();
			}
		}
	}
	catch(const std::exception& ex)
	{
		LOG(LERR, "Exception caught: %s", ex.what());
	}

	return ret;
}

bool CConvert::SetElementValue(xmlpp::Element* elem, string elmentName, string strval)
{
	try 
	{
		xmlpp::Element* val = elem->add_child(elmentName);
		val->set_child_text(strval);
	}
	catch(const std::exception& ex)
	{
		LOG(LERR,"Exception caught: %s",ex.what() );
		return false;
	}	

	return true;	
}

string CConvert::GetJobMapValue(void *pDataMap, string key)
{
	string r;
	CJobDataMap *pMap = reinterpret_cast<CJobDataMap *>(pDataMap);
	CJobDataMap::iterator it;
	it = pMap->find(key);
	if(it != pMap->end())
	{
		r = it->second;
	}
	else
	{
		LOG(LDEV2, "Map Data Empty(Key:%s)", key.c_str());
	}
	return r;
}

int32_t CConvert::ToClientResult(int nServiceType, int nEnd)
{
	int32_t r = JOB_SUCCESS;

	// rc_tsd와 통신하는 client 호환성을 위한 코드 
	switch(nEnd)
	{
	case JOB_SUCCESS:
		{
			switch(nServiceType)
			{
			case CServiceInfo::SDK:
				// rc_tsd와 통신하는 client 호환성을 위한 코드
				r = SDK_RES_OK_ALL_PASSED;
				break;
			case CServiceInfo::ETC:
				// rc_cchkd와 통신하는 client 호환성을 위한 코드
				r = ETC_RES_SUCCESS;
				break;
			case CServiceInfo::XML:				
				// rc_mngd에서 정의가 에러 코드 값 그대로 리턴
			default:
				r = nEnd;
				break;
			}
		}
		break;
	default:
		{
			switch (nServiceType)
			{
			case CServiceInfo::SDK:
				// rc_tsd와 통신하는 client 호환성을 위한 코드
				r = SDK_RES_SERVER_ERR;
				break;
			default:
				r = JOB_ERR_UNKNOWN;
				break;
			}
		}
	}
	return r;
}


// Abstract Factory returning a Convert
CConvert* CConvertFactory::CreateConvert(string & szBodyType, string & subType)
{
	_LOG( LDBG, "Convert Factory [%s]",szBodyType.c_str());
	CConvert * r = NULL;
	if( szBodyType.compare(XML_STR_TYPE_OPEN) == 0 
		|| szBodyType.compare(XML_STR_TYPE_MOVE) == 0 
		|| szBodyType.compare(XML_STR_TYPE_OPEN_N_SYNC) == 0 
		|| szBodyType.compare(XML_STR_TYPE_MOVE_N_SYNC) == 0)
	{
		_LOG( LDBG, "Convert Factory [%s|%s]",szBodyType.c_str(),JOB_SERVICE_OPEN);
		r = new CConvertServiceOpen;
	}
	else if( szBodyType.compare(XML_STR_TYPE_CHANGE) == 0 )
	{
		if (subType.compare(XML_STR_USER_PASSWORD) == 0) 
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_USER);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_USER_PW);
		}
		else if (subType.compare(XML_STR_SVC_STGSIZE) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_STORAGE);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_STORAGE);
		}
		else if (subType.compare(XML_STR_SVC_SERVICEDATE) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_PERIOD);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_PERIOD);
		}
		else if (subType.compare(XML_STR_TRAFFICLIMIT) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_BAND_VOLUME_LIMIT);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_BAND_VOLUME_LIMIT);
		}
		else if (subType.compare(XML_STR_SVC_CUSTOMAUTH) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_EXAUTH_INFO);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_EXAUTH_INFO);
		}
		else if (subType.compare(XML_STR_SVC_STATUS) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_STATUS);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_STATUS);
		}
		else if (subType.compare(XML_STR_SVC_REPLICA) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_REPLICATION);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_REPLICATION);
		}
		else if (subType.compare(XML_STR_SVC_URIIGNORECASE) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_IGNORE_CASE);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_IGNORE_CASE);
		}
		else if (subType.compare(XML_STR_SVC_URIIGNORECASEFRORCE) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_SERVICE_CHANGE, XML_STR_SVC_URIIGNORECASEFRORCE);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_IGNORE_CASE_FROCE);
		}
		else if (subType.compare(XML_STR_SVC_DELFILEKEEPTIME) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_DEL_FILE_KEEP_TIME);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_DEL_FILE_KEEP_TIME);
		}
		else if (subType.compare(XML_STR_SVC_USEDSIZECALCDEPTH) == 0)
		{			
			_LOG( LDBG, "Convert Factory [%s-%s]",JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_STORAGE_CAL);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_STORAGE_CAL);
		}
		else if (subType.compare(XML_STR_SVC_SYNC_LINK) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_SERVICE_CHANGE, JOB_SERVICE_CHG_SYNC);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_SYNC);
		}
		else if (subType.compare(XML_STR_SVC_MOVE_REQ) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_SERVICE_CHANGE, JOB_SERVICE_CHG_MOVE_RQE);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_MOVE_RQE);
		}
		else if (subType.compare(XML_STR_SVC_MOVE_COPM) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_SERVICE_CHANGE, JOB_SERVICE_CHG_MOVE_COMP);
			r = new CConvertServiceChange(JOB_SERVICE_CHG_MOVE_COMP);
		}
		else 
		{
			r = NULL;
		}
	}
	else if (szBodyType.compare(XML_STR_TYPE_FILE) == 0)
	{
		if (subType.compare(XML_STR_FILE_EXIST) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_FILE_CTL, JOB_FILE_CTL_EXIST);
			r = new CConvertFileControl(JOB_FILE_CTL_EXIST);
		}
		else if (subType.compare(XML_STR_FILE_MKDIR) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_FILE_CTL, JOB_FILE_CTL_MKDIR);
			r = new CConvertFileControl(JOB_FILE_CTL_MKDIR);
		}
		else if (subType.compare(XML_STR_FILE_FRONT_10M_MD5) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_FILE_CTL, JOB_FILE_CTL_GET_HASH_10MB);
			r = new CConvertFileControl(JOB_FILE_CTL_GET_HASH_10MB);
		}
		else if (subType.compare(XML_STR_FILE_TOTO_EXTRACT_WITHPLATFORM) == 0)
		{
			_LOG(LDBG, "Convert Factory [%s-%s]", JOB_FILE_CTL, JOB_FILE_CTL_TOTO_EXTRACT_WITHPLATFORM);
			r = new CConvertFileControl(JOB_FILE_CTL_TOTO_EXTRACT_WITHPLATFORM);
		}
		else
		{
			r = NULL;
		}
	}
	else 
	{
		r = NULL;
	}

	if ( r == NULL )
	{
		LOG(LERR, "Body Type is unknown.[%s]", szBodyType.c_str());
	}

	return r;
}

CConvert* CConvertFactory::CreateConvert(int nBodyType)
{
	CConvert * r = NULL;
	switch(nBodyType)
	{
	case SDK_REQ_OPEN_SERVICE:
		_LOG( LDBG, "Convert Factory [%d|%s]",nBodyType,JOB_SERVICE_OPEN);
		r = new CConvertServiceOpen;
		break;
	case SDK_REQ_CHG_USER_INFO:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_USER);
		r = new CConvertServiceChange(JOB_SERVICE_CHG_USER_PW);
		break;
	case SDK_REQ_CHG_STORAGE:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_STORAGE);
		r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_STORAGE);
		break;
	case SDK_REQ_CHG_BANDWIDTH:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_BANDWIDTH);
		r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_BANDWIDTH);
		break;
	case SDK_REQ_CHG_PERIOD:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_PERIOD);
		r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_PERIOD);
		break;
	case SDK_REQ_CHG_AUTHINFO:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_SERVICE_CHANGE,JOB_SERVICE_CHG_PRODUCT_AUTHINFO);
		r = new CConvertServiceChange(JOB_SERVICE_CHG_PRODUCT_AUTHINFO);
		break;
	case SDK_REQ_VOLUME_INFO:
		_LOG( LDBG, "Convert Factory [%d|%s]",nBodyType,JOB_VOLUME_INFO);
		r = new CConvertVolumeInfo;
		break;
	case SDK_REQ_SET_ANONY_DIR:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_ANONY_DIR,JOB_ANONY_DIR_SET);
		r = new CConvertAnonymosDir(JOB_ANONY_DIR_SET);
		break;
	case SDK_REQ_UNSET_ANONY_DIR:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_ANONY_DIR,JOB_ANONY_DIR_UNSET);
		r = new CConvertAnonymosDir(JOB_ANONY_DIR_UNSET);
		break;
	case SDK_REQ_ANONY_DIR:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_ANONY_DIR,JOB_ANONY_DIR_GET);
		r = new CConvertAnonymosDir(JOB_ANONY_DIR_GET);
		break;
	case ETC_REQ_GETFILE_HASH_MD5_10MB:
		_LOG( LDBG, "Convert Factory [%d|%s-%s]",nBodyType,JOB_FILE_CTL,JOB_FILE_CTL_GET_HASH_10MB);
		r = new CConvertFileControl(JOB_FILE_CTL_GET_HASH_10MB);
		break;
	default:
		r = NULL;
		LOG(LERR, "Body Type is unknown.[%d|NULL]",nBodyType);
		break;
	}

	return r;
}

CConvert* CConvertFactory::CreateConvert(xmlpp::Node* node, void *pDataMap/* = NULL*/)
{
	CConvert * r = NULL;
			
	try 
	{
		const xmlpp::Element* job = dynamic_cast<const xmlpp::Element*>(node);

		if(job == NULL)
		{
			LOG(LERR, "unknown.[job = NULL]");
			return r;
		}

		string jobtype = job->get_attribute_value(XML_STR_JOB_TYPE);
		string subtype = job->get_attribute_value(XML_STR_JOB_TYPE_LIST);

		LOG(LDBG, "XML : %s(%d|%s,%s)", job->get_name().c_str(), 
			(int)job->get_attributes().size(),jobtype.c_str(), subtype.c_str());

		if(pDataMap)
		{
			CJobDataMap *pMap = reinterpret_cast<CJobDataMap *>(pDataMap);
			pMap->insert(CJobDataPair(KEY_RES_XML_JOB_TYPE, jobtype));
			pMap->insert(CJobDataPair(KEY_RES_XML_JOB_TYPE_List, subtype));
		}
		else 
		{
			LOG(LWAR, "Map Object is NULL.");
		}

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