#include <errno.h>
#include <string.h>
#include "MasterJobThread.h"
#include "GetSource.h"
#include "MakeSyncFile.h"
#include "Synchronization.h"

CMasterJobThread::CMasterJobThread(CSyncInfo info, CWorkResult* pResult)
	: m_info(info)
	,m_pResult(pResult)
{
	m_threadHandle = 0;
}

CMasterJobThread::~CMasterJobThread()
{
	// Thread 동작 정지 처리
	// - 만약 Thread 가 이미 종료된 경우 m_threadHandle 이 다른 Thread Handle 일 수 있으므로  업무 Flow 수정시 주의할 것
	//if( m_threadHandle != 0 )
		//pthread_cancel( m_threadHandle );
}

// thread 를 생성하여 처리 업무 flow start
bool CMasterJobThread::Start()
{
	int nRet = ::pthread_create( &m_threadHandle, NULL, CMasterJobThread::threadFunc, this );
	if( nRet != 0 )
	{
		// Thread 생성 실패시
		int errorNum = errno;
		LOG( LERR, "Thread create failed.[%d][%s]", errorNum, strerror( errorNum ) );

		return false;
	}
	return true;

}

// 스레드 함수
void* CMasterJobThread::threadFunc( void* arg )
{
	CMasterJobThread* pObject = reinterpret_cast<CMasterJobThread *>( arg );
	
	//pthread_detach( pthread_self() );
	// 실제 작업 수행.
	pObject->Execute();

	// 생성된 파일 삭제 처리
	pObject->m_info.UnlinkFile();
	
	// 객체 자동 delete 처리.
	//delete pObject;	
	return NULL;
}

// 실제 업무 flow를 정의 한다.
void CMasterJobThread::Execute()
{
	string strMessage;
	// 동기화 대상 파일 수집
	CGetSource objGetSource(m_info);
	if( objGetSource.GetSource(CGetSource::BOTH) == false )
	{
		LOG( LERR, "Get Source file failed.");
		m_pResult->bSuccess = false;
		m_pResult->strMasterID = m_info.sync_master;
		m_pResult->strRcts = m_info.sync_rcts;
		m_pResult->strMessage = "Get Source file failed.";
		m_pResult->strSyncFileName = "";
		return;
	}
	
	// sync file 생성..
	CMakeSyncFile objMakeSyncfile(m_info);
	if( objMakeSyncfile.MakeSyncFile() == false )
	{
		LOG( LERR, "Sync file make failed.");
		m_pResult->bSuccess = false;
		m_pResult->strMasterID = m_info.sync_master;
		m_pResult->strRcts = m_info.sync_rcts;
		m_pResult->strMessage = "Sync file make failed.";
		m_pResult->strSyncFileName = "";
		return;
	}
	
	// sync 요청 처리.
	CSynchronization objSynchronization(m_info);
	int r = objSynchronization.ExcuteSync();
	if (r  < 0 )
	{
		LOG( LERR, "Synchronization request failed.");
		m_pResult->bSuccess = false;
		m_pResult->strMasterID = m_info.sync_master;
		m_pResult->strRcts = m_info.sync_rcts;
		m_pResult->strMessage = "Synchronization request failed.";
		m_pResult->strSyncFileName = "";
		return;
	}

	if (m_info.sync_type > SYNC_TYPE::NORMA_N_ONLY)
	{
		m_pResult->strMessage = "Get sync file Success.";
		// 파일명 추가
		m_pResult->strSyncFileName = r == 0 ? "" : m_info.file_sync_name;
	}
	else
	{
		m_pResult->strMessage = "Synchronization request Success.";
		m_pResult->strSyncFileName = "";
	}

	m_pResult->bSuccess = true;
	m_pResult->strMasterID = m_info.sync_master;
	m_pResult->strRcts = m_info.sync_rcts;

	LOG(LDBG, "%s", m_pResult->strMessage.c_str());
}
