/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012                                                                         *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
    Description:
    Cette classe permet de connaître la quantité de RAM utilisée par le programme.

*/

/* ************************************************************************** */
/* Revision:
### 20121219 JFM
    Verision d'origine.
    
### YYYYMMDD Description du besoin ou du bug
    Description du changement.
 */

/* ************************************************************************** */

#include "RamMonitor.h"
#include <QDateTime>
#include <unistd.h>

//singleton instantiation
CRamMonitor CRamMonitor::mSingleton;

CRamMonitor::CRamMonitor()
{
	mLastRamUsage = 0;
	GetRamUsage();

	connect(&mRamUsageTimer,SIGNAL(timeout()),this,SLOT(RamUsageTimerExpired()));

	QString FileName;
	FileName = "./LOG/RamLog.csv";

#ifdef LOG_RAM_USAGE
	mRamLogFile = new QFile(FileName);
	if(mRamLogFile)
	{
		mRamLogFile->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text | QIODevice::Unbuffered);

		QString temp;
		mRamLogFile->write(temp.sprintf("********************************************************************\n").toAscii().data());
		mRamLogFile->write(temp.sprintf("Création le %s à %s\n",QDateTime::currentDateTime().date().toString("yyyy-MM-dd").toAscii().data(),QDateTime::currentDateTime().time().toString("hh:mm:ss").toAscii().data()).toAscii().data());
		mRamLogFile->write(temp.sprintf("********************************************************************\n").toAscii().data());
	}
#endif
}

CRamMonitor::~CRamMonitor()
{
#ifdef LOG_RAM_USAGE
	mRamLogFile->close();
	delete mRamLogFile;
#endif
}

long CRamMonitor::GetRamUsage(bool print)
{
	long rss = 0;
	FILE *fp = NULL;
	if((fp = fopen("/proc/self/statm","r")) == NULL)
	{
		fclose(fp);
		if(print)
			qDebug("cannot open statm");

		return 0;
	}
	else
	{
		if(fscanf(fp,"%*s%ld",&rss) != 1)
		{
			fclose(fp);

			if(print)
				qDebug("Cannot read ram size");

			return 0;
		}
		else
		{
			fclose(fp);
			rss *= (long)sysconf(_SC_PAGESIZE);

			if(print)
				qDebug("Ram usage: %ld",rss);

			mLastRamUsage = rss;
			return rss;
		}
	}

	//return rss;
}

long CRamMonitor::GetRamDelta(bool print)
{
	long rss = 0;
	FILE *fp = NULL;
	if((fp = fopen("/proc/self/statm","r")) == NULL)
	{
		fclose(fp);
		if(print)
			qDebug("cannot open statm");

		return 0;
	}
	else
	{
		if(fscanf(fp,"%*s%ld",&rss) != 1)
		{
			fclose(fp);

			if(print)
				qDebug("Cannot read ram size");

			return 0;
		}
		else
		{
			fclose(fp);
			rss *= (long)sysconf(_SC_PAGESIZE);

			if(print)
			{
				qDebug("Ram usage: Previous = %ld [%ldk], Actual = %ld [%ldk], Delta = %ld [%ldk]",mLastRamUsage,mLastRamUsage/1024,rss,rss/1024,(rss-mLastRamUsage),(rss-mLastRamUsage)/1024);
			#ifdef LOG_RAM_USAGE
				mRamLogFile->write(QString().sprintf("%ld\n",rss).toAscii().data());
			#endif
			}

			mLastRamUsage = rss;
			return rss;
		}
	}
}

void CRamMonitor::StartTimer()
{
	mRamUsageTimer.setSingleShot(false);
	mRamUsageTimer.start(5000);
}

void CRamMonitor::StopTimer()
{
	mRamUsageTimer.stop();
}

void CRamMonitor::RamUsageTimerExpired()
{
	GetRamDelta(true);
}
