#include <iostream>
#include <boost/format.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "boost/filesystem.hpp"
#include "boost/filesystem/operations.hpp"

using boost::format;
using boost::asio::ip::tcp;
using namespace boost::filesystem;
using namespace std;
using namespace boost::posix_time;

struct Tes
{
	int m_nVal;
};

boost::asio::io_service m_ioService(5);
boost::thread_group m_serviceRun;
boost::recursive_mutex m_threadCountMutex;
boost::shared_ptr<boost::asio::io_service::strand> m_ioStrand;
boost::shared_ptr<boost::asio::deadline_timer> m_testTimer;

void RunService()
{
	for (;;)
	{
		try
		{
			cout<<"Run application."<<endl;
			m_ioService.run();
			cout<<"Run exit."<<endl;
			break;
		}
		catch (boost::system::system_error & e)
		{
			// Deal with exception as appropriate.
			string temp(e.what());
			temp="Error in Run"+temp;
			cout<<e.what()<<endl;
		}
	}
}

void Initialize(int threads)
{
	boost::recursive_mutex::scoped_lock lock(m_threadCountMutex);

	for ( int i = 0; i < threads; ++i)
	{
		m_serviceRun.create_thread( &RunService );
	}
	cout<<str(format("Initialize threads  %1% Total Thread %2%")%threads  %m_serviceRun.size())<<endl;
}

void Join()
{
	cout<<"joining io service"<<endl;
	m_serviceRun.join_all();
	cout<<"joining io service done"<<endl;
}

void TestTimer(const boost::system::error_code& error)
{
	try
	{
		if (error == boost::asio::error::operation_aborted)
		{
			cout<<"TestTimer canceled"<<endl;
			return;
		}
		cout<<"Timer fired. Boost thread is working."<<endl;
	}
	catch (boost::system::system_error & e)
	{
	}

}

int main(int argc, char* argv[])
{
	//Boost shared pointer test code
	boost::shared_ptr<Tes> myTes(new Tes);
	myTes->m_nVal=10;
	cout<<"Boost shared pointer is wroking : "<<myTes->m_nVal<<endl;

	//Boost filesystem test code
	string dirpath="/tmp";
	path dpath(dirpath);
	cout<<"Boost filesystem is wroking"<<endl;
	if(exists(dpath))
		cout<<"Folder Exist"<<dpath<<endl;
	else
		cout<<"Folder Not Exist"<<dpath<<endl;

	//Boost thread test code
	m_ioStrand.reset(new boost::asio::io_service::strand(m_ioService));
	m_testTimer.reset(new boost::asio::deadline_timer(m_ioService));
	m_testTimer->expires_from_now(seconds(5));
	m_testTimer->async_wait(m_ioStrand->wrap(boost::bind(&TestTimer,_1)));
	Initialize(2);

	Join();

	return 0;
}
