#include "Config.h"
#include "GcmdConfig.h"
#include "ProcessStatus.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


#define DEFAULT_MAX_THREAD	100

using namespace std;

CGcmdConfig::CGcmdConfig( std::string szFilename, std::string szProgramName, std::string szProgramVersion )
{
	m_szConfigFile		= szFilename;
	m_szProgramName		= szProgramName;
	m_szProgramVersion	= szProgramVersion;
	m_szErrMessage		= "";
	
	/// COMMON Section
	m_szAppLogRoot = "";
	m_nLogLevel	= 0;
	// end..
	
	m_nMaxDeleteThread = 0;
}

CGcmdConfig::~CGcmdConfig()
{
}

bool CGcmdConfig::LoadConfig()
{
	string szValue;
	std::vector< std::string > vecValue;
	
	/// Config 처리를 위한 객체 생성
	Config conf;
	
	/// Config File open
	if( conf.Open( m_szConfigFile ) == false )
	{
		m_szErrMessage = "Config file open failed.[" + m_szConfigFile + "]";
		return false;
	}
	
	// [COMMON] - RCDB_IP(multi string value)
	szValue.clear();
	if( conf.GetConfig( "COMMON", "RCDB_IP", szValue ) == false )
	{
		m_szErrMessage = "Config info get failed. [COMMON]->RCDB_IP";
		return false;
	}
	m_szRcdbIp = szValue;
	
	// [COMMON] - RCDB_PORT (int)
	szValue.clear();
	if( conf.GetConfig( "COMMON", "RCDB_PORT", szValue ) == false )
	{
		m_szErrMessage = "Config info get failed. [COMMON]->RCDB_PORT";
		return false;
	}
	
    m_nRcdbPort = atoi(szValue.c_str());
	// [COMMON] - RCDB_DB_NAME (string)	
	szValue.clear();
	if( conf.GetConfig( "COMMON", "RCDB_DB_NAME", szValue ) == false )
	{
		m_szErrMessage = "Config info get failed. [COMMON]->RCDB_DB_NAME";
		return false;
	}
    m_szRcdbName = szValue;
    
	// [COMMON] - RCDB_ACCT (string)
	szValue.clear();
	if( conf.GetConfig( "COMMON", "RCDB_ACCT", szValue ) == false )
	{
		m_szErrMessage = "Config info get failed. [COMMON]->RCDB_ACCT";
		return false;
	}
    m_szRcdbAcct = szValue;
    
	// [COMMON] - RCDB_ACCT_PW (string)
	szValue.clear();
	if( conf.GetConfig( "COMMON", "RCDB_ACCT_PW", szValue ) == false )
	{
		m_szErrMessage = "Config info get failed. [COMMON]->RCDB_ACCT_PW";
		return false;
	}
	m_szRcdbAcctPw = szValue;
    

	
	/// log path
	szValue.clear();
	if( conf.GetConfig( "rc_gcmd", "DEFAULT_LOG_DIR", szValue ) == false )
	{
		if( conf.GetConfig( "COMMON", "DEFAULT_LOG_DIR", szValue ) == false )
		{
			m_szErrMessage  = "Config info get failed. [" + m_szProgramName + "]->LOG_DIR";
			return false;
		}
	}
	m_szAppLogRoot = szValue;
		
	// log level
	szValue.clear();
	if( conf.GetConfig( "rc_gcmd", "LOG_LEVEL", szValue ) == false )
	{
		if( conf.GetConfig( "COMMON", "LOG_LEVEL", szValue ) == false )
		{
			m_szErrMessage  = "Config info get failed. [" + m_szProgramName + "]->LOG_LEVEL";
			return false;
		}
	}
	m_nLogLevel = atoi( szValue.c_str() );
	
	// max delete thread
	szValue.clear();
	if( conf.GetConfig( "rc_gcmd", "MAX_DELETE_THREAD", szValue ) == false )
	{   
		m_szErrMessage  = "Config info get failed. [" + m_szProgramName + "]->MAX_DELETE_THREAD";
		return false;
	}   
    m_nMaxDeleteThread = atoi( szValue.c_str() );
    
	if ( CheckConfig() == false )
    {
        return false;
    }
    
	/// 싱클톤 객체인 Process Satatus에 값을 저장해 둔다.
	// common section configure values
	CProcessStatus::GetInstance()->SetProgramName(m_szProgramName);
	CProcessStatus::GetInstance()->SetProgramVersion(m_szProgramVersion);
	CProcessStatus::GetInstance()->SetLogLevel(m_nLogLevel);
	CProcessStatus::GetInstance()->SetAppLogRoot(m_szAppLogRoot);
	
	CProcessStatus::GetInstance()->SetRcdbIp(m_szRcdbIp);
	CProcessStatus::GetInstance()->SetRcdbPort(m_nRcdbPort);
	CProcessStatus::GetInstance()->SetRcdbName(m_szRcdbName);
	CProcessStatus::GetInstance()->SetRcdbAcct(m_szRcdbAcct);
	CProcessStatus::GetInstance()->SetRcdbAcctPw(m_szRcdbAcctPw);
	CProcessStatus::GetInstance()->SetMaxDeleteThread(m_nMaxDeleteThread);
	
	return true;
}

bool CGcmdConfig::CheckConfig()
{
    if( m_szRcdbIp.empty() )
	{
		m_szErrMessage = "[COMMON]->RCDB_IP is empty.";
		return false;
	}
	
	if ( m_nRcdbPort <= 0 )
	{
        m_szErrMessage  = "Config value not valid.[COMMON]->RCDB_PORT = [";
		m_szErrMessage += m_nRcdbPort;
		m_szErrMessage +=  "]";
		return false;
    }
    
    if( m_szRcdbName.empty() )
	{
		m_szErrMessage = "[COMMON]->RCDB_DB_NAME is empty.";
		return false;
	}
    if( m_szRcdbAcct.empty() )
	{
		m_szErrMessage = "[COMMON]->RCDB_ACCT is empty.";
		return false;
	}
    if( m_szRcdbAcctPw.empty() )
	{
		m_szErrMessage = "[COMMON]->RCDB_ACCT_PW is empty.";
		return false;
	}
	
	if ( m_nMaxDeleteThread <= 0 )
	{
    	m_szErrMessage  = "Config info get failed. [" + m_szProgramName + "]->MAX_DELETE_THREAD";
		m_szErrMessage += m_nMaxDeleteThread;
		m_szErrMessage +=  "]";
		return false;
    }
    if ( m_nMaxDeleteThread > DEFAULT_MAX_THREAD )
    {
    	m_nMaxDeleteThread = DEFAULT_MAX_THREAD;
    }
    
	return true;
}

bool CGcmdConfig::CheckVector(std::vector< std::string > vecValue)
{
	// Multi value 이므로 갯수 검사
	if( vecValue.size() <= 0 )
	{
		return false;
	}
	
	// 각 데이터별 유효성 여부 검사.
	std::vector< std::string >::const_iterator it;
	for( it = vecValue.begin(); it != vecValue.end(); it++ )
	{
		if( it->size() <= 0 )
		{
			return false;
		}
	}
	return true;
}
