/***************************************************************************
                CDataFile
                -----------------------------------------
	begin      : 2011/10/28
	copyright  : (C) 2011 SolutionBox Inc.
	author     : Service 1 Team
	email      : svc1@solbox.com
	version    : 3.0.1

    CopyRight(C) 2011 SolutionBox Inc. All Rights reserved.
    Redistribution and use in source and binary forms, with or with out
    modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/
#include "DataFile.h"
#include "Logger.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>


// 임시 버퍼 최대 크기
#define MAX_BUFFER_SIZE	2048


CDataFile::CDataFile()
{
}

CDataFile::~CDataFile()
{
}

bool CDataFile::Init(const char* path, bool chkdir /*= true*/)
{
	ostringstream msg;
	// 변수 유효성 검사.
	if( path == NULL || strlen( path ) == 0 )
	{
		msg << "Wrong path info(" << path << ")";
		LOG(LERR, msg.str().c_str());
		return false;
	}		

	// 변수 정보 Setup
	if (strlen(path) > 0)
	{
		m_strFilePath.clear();
		m_strFileName.clear();

		string strFullPath(path);
		int nFind = strFullPath.rfind("/") + 1;
		m_strFilePath = strFullPath.substr(0, nFind-1);
		m_strFileName = strFullPath.substr(nFind, strFullPath.size() - nFind);
	}

	LOG(LDBG, "Data File %s, %s", m_strFilePath.c_str(), m_strFileName.c_str());
	if(m_strFilePath.size() <= 0 && m_strFileName.size() <= 0)
	{   
		msg << "Wrong path info(" << path << ")";
		LOG(LERR, msg.str().c_str());
		return false;                                                                             
	}  

	if (chkdir)
	{
		// FLOW상 중복파일이 발생할 수 없지만.. 혹시 생기면 전체 데이터에 영향을 줄 수 있기때문에 방어 코드 삽입
		Delete();

		struct stat dirStat;
		// 디렉토리 정보 검사
		if (lstat(m_strFilePath.c_str(), &dirStat) != 0)
		{
			// Directory 가 존재하지 않는 경우 Directory 생성 시도
			if (mkdir(m_strFilePath.c_str(), 0755) != 0)
			{
				if (errno != EEXIST)
				{					
					msg << "DataFile directory create failed : [" << path << "]";
					LOG(LERR, msg.str().c_str());

					return false;
				}
			}
		}
	}

	LOG(LDBG, "check CDataFile::Init");

	return true;
}

bool CDataFile::Write(const char* fmt, ...)
{
	if(m_strFilePath.size() <= 0 || m_strFileName.size() <= 0)
		return false;

	// DataFile file open
	FILE* pFile = NULL;
	string strFullName = m_strFilePath + "/" +m_strFileName;

	pFile = fopen( strFullName.c_str(), "a+" );
	if( pFile == NULL )
	{
		ostringstream msg;
		msg << "DataFile file open fail : [" << strFullName << "]";
		LOG(LERR, msg.str().c_str());

		return false;
	}

	// 가변 인자 처리
	va_list args;
	char buffer[MAX_BUFFER_SIZE];
	va_start( args, fmt );
	if( vsnprintf( buffer, MAX_BUFFER_SIZE, fmt, args) < 0 )
	{
		va_end( args );
		fclose( pFile );
		return false;
	}
	va_end(args);

	// Write to DataFile file
	if(strlen(buffer) > 0)
		fprintf( pFile, "%s\n", buffer );

	fflush( pFile );

	// 종료 처리.
	fclose( pFile );
	return true;
}

bool CDataFile::Delete()
{
	if(m_strFilePath.size() <= 0 || m_strFileName.size() <= 0)
		return false;

	string strFullName = m_strFilePath + m_strFileName;

	bool bReturn = Delete(strFullName.c_str());

	if(bReturn)
	{
		m_strFilePath.clear();
		m_strFileName.clear();
	}

	return bReturn;
}

bool CDataFile::Delete(const char* path)
{
	// 변수 유효성 검사.
	if(path == NULL || strlen(path) == 0)
		return false;
	
	struct stat dirStat;
	// 디렉토리 정보 검사
	if(lstat(path, &dirStat ) == 0)
	{
		remove(path);

		ostringstream msg;
		msg << "DataFile file delete success : [" << path << "]";
		LOG(LDBG, msg.str().c_str());
	}
	else
	{
		ostringstream msg;
		msg << "DataFile file delete failed : [" << path << "]";
		LOG(LDBG, msg.str().c_str());

		return false;
	}

	return true;
}
