#include "rc_cmove.h"
#include "Logger.h"

void StringSplit(string str, string delim, vector<string> &results, bool bUseEmpty /*= false*/)
{
	const string strEmpty("");
	string::size_type cutAt;

	while( (cutAt = str.find_first_of(delim)) != str.npos )
	{
		if(cutAt > 0)
		{
			results.push_back(str.substr(0,cutAt));
		}
		else
		{
			if(bUseEmpty && cutAt == 0)
				results.push_back(strEmpty);
		}
		str = str.substr(cutAt+1);
	}
	
	//if(str.length() > 0)
	{
		results.push_back(str);
	}
}

int StringCount(string str, string delim)
{
	int nCount = 0;
	string::size_type cutAt;

	while((cutAt = str.find_first_of(delim)) != str.npos)
	{
		if(cutAt > 0)
		{
			nCount++;
		}
		str = str.substr(cutAt+1);
	}
	if(str.length() > 0)
		nCount++;

	return nCount;
}

#define USEC_PER_SEC    (1000000LL)
long long longtime_now()
{
	struct timeval tv;

	if( gettimeofday(&tv, NULL) == 0 )
	{
		// 성공시 micro-second 단위의 값을 반환
		return tv.tv_sec * USEC_PER_SEC + tv.tv_usec;	
	}
	else
	{
		// 실패시 -1 값을 반환.
		return -1;
	}
}

string strtime_now()
{
	time_t rawtime;
	struct tm * timeinfo;
	char buffer [16] = {0};

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );

	if ( strftime (buffer,sizeof buffer, "%Y%m%d%H%M%S",timeinfo) <= 0 )
		return "";

	return string(buffer);
}

time_t str2time_t(string strtime)
{
	struct tm tm = {0};

	if( strtime == "0" )
		return 0;

	if ( strptime (strtime.c_str(), "%Y%m%d%H%M%S", &tm) == NULL )
		return -1;

	return mktime(&tm);
}

long long str2longtime(string strtime)
{
	return str2time_t(strtime) * USEC_PER_SEC;
}

long GetFileSize(const char* path)
{
	long size	= -1;
	int flag	= -1;
	struct stat buf;

	flag = stat(path, &buf);
	if(flag == -1)
	{
		cerr << "file not found : " << path << endl;
		return -1;
	}
	size = buf.st_size;

#ifdef _DEBUG
	if(size == 0)
		cout << "file size zero : " << path << endl;
#endif // _DEBUG

	return size;
}

string getCommand(string cmd) 
{
	string data;
	FILE *stream;
	int MAX_BUFFER = 256;
	char buffer[MAX_BUFFER];
	cmd.append(" 2>&1");
	LOG(LDEV1, "[POPNE] OPEN %s ", cmd.c_str());

	stream = popen(cmd.c_str(), "r");
	if (!stream)
	{
		LOG(LERR, "[POPNE] popen error. [%s] ", cmd.c_str());
		return "";
	}

	LOG(LDEV1, "[POPNE] READ %s ", cmd.c_str());
	memset(buffer,0,MAX_BUFFER);	
	while(fgets(buffer, MAX_BUFFER, stream)) 
	{
		LOG(LDEV1, "[POPNE] READING.. %s|%s ", cmd.c_str(), buffer);
		data.append(buffer);
		memset(buffer,0, MAX_BUFFER);	
	}
	LOG(LDEV1, "[POPNE] READ END %s ", cmd.c_str());

	if (ferror(stream))
	{
		// Handle error.
		LOG(LERR, "[POPNE] Handle error. [%s] ", cmd.c_str());
		return "";
	}

	pclose(stream);
	return data;
}

string StringReplace(const string& source, const string search, const string replacement)
{
	string r = source;

	string::size_type pos = 0;

	while ( (pos = r.find(search, pos)) != string::npos ) 
	{
		r.replace( pos, search.size(), replacement );
		pos = pos + replacement.size();		
	}

	return r;
}

void solusleep(unsigned long usec)
{
	// usleep 사용시 multi thread 환경에서 block 발생 가능성이 존재
	// 이에 nanosleep 함수를 사용토록 수정 처리함.
	struct timespec sleep;

	if (usec >= 1000000)
	{
		sleep.tv_sec = (int)(usec / 1000000);
		sleep.tv_nsec = (usec - ((long)sleep.tv_sec * 1000000)) * 1000;
	}
	else 
	{
		sleep.tv_sec = 0;
		sleep.tv_nsec = usec * 1000;
	}
	
	nanosleep(&sleep, NULL);
}