#include "Utils.h"
#include "common/windows/FOutStream.h"
#include <stdio.h>
#include <stdarg.h>

#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>

#include "platform.h"

#if defined(ANDROID)
#include <sys/time.h>
#endif


using namespace NS_DM_Client::NS_Common;

	FOutStream::FOutStream(): m_file(0)
	{
	}
	//-------------------------------------------------------------------------------------------

	FOutStream::~FOutStream()
	{
	}
	//-------------------------------------------------------------------------------------------

	void FOutStream::Open(const char* filename)
	{
		m_file = fopen(filename, "a");
		if (!m_file)
		{
			printf("ERROR: Cannot create logfile %s", filename);
			return;
		}
	}
	//-------------------------------------------------------------------------------------------

	void FOutStream::Close()
	{
		fclose(m_file); 
	}
	//-------------------------------------------------------------------------------------------

	void FOutStream::Write(const char* buffer, int size)
	{
		if (!m_file)
			return;
		size_t count = fwrite(buffer, sizeof(char), size, m_file);
		if ((int)count < size)
		{
			printf("WARNING: Failed to write all message to file");
		}
		int res = fflush(m_file);
		if (res != 0)
		{
			printf("WARNING: Failed to flush file's buffer");
		}
	}
	//-------------------------------------------------------------------------------------------

	int FOutStream::FormatMessage(char* buffer, int size, int threadID, const char* loggerName, 
		const char* category, const char* functionName)
	{ 
#ifdef PLATFORM_WINDOWS
		struct _timeb tstruct;
		_ftime(&tstruct);
		//_ftime_s(&tstruct); 
		char tmpbuf[128];
		_strtime(tmpbuf);
		//_strtime_s( tmpbuf, 128);

		int written = _snprintf(buffer, size, "%s.%03u %5u %s %s %s", tmpbuf, tstruct.millitm, 
			threadID, loggerName, functionName, category);
#elif defined ANDROID
		struct timeval start;
		gettimeofday(&start, NULL);
		struct tm * ptm = localtime(&start.tv_sec);
		int written = snprintf(buffer, size, "%02d:%02d:%02d.%03u %5u %s %s %s", ptm->tm_hour, ptm->tm_min, ptm->tm_sec, start.tv_usec/1000,
							   threadID, loggerName, functionName, category);
#endif
		return written;
	}
	//-------------------------------------------------------------------------------------------

	int FOutStream::FormatMessage(char* buffer, int size, int threadID, const char* loggerName, const char* category)
	{
#ifdef PLATFORM_WINDOWS
		struct _timeb tstruct;
		_ftime_s(&tstruct); 
		char tmpbuf[128];
		_strtime_s(tmpbuf, 128);

		int written = _snprintf(buffer, size, "%s.%03u %5u %s %s", tmpbuf, tstruct.millitm, threadID, 
			loggerName, category);
#elif defined ANDROID
		struct timeval start;
		gettimeofday(&start, NULL);
		struct tm * ptm = localtime(&start.tv_sec);
		int written = snprintf(buffer, size, "%02d:%02d:%02d.%03u %5u %s %s", ptm->tm_hour, ptm->tm_min, ptm->tm_sec, start.tv_usec/1000,
							   threadID, loggerName, category);
#endif

		return written;
	}
