// ThriftCommon.h : Common includes, namespaces and templates 
// for sample Thrift client and server
//
// Add the following paths to the Project's properties:
//
// Configuration Properties -> C/C++ -> General-> Additional Include Directories --
// ../;../../../lib/cpp/src;../../../../boost;../../../../boost/boost/tr1;
//
// Configuration Properties -> Linker -> General -> Additional Library Directories --
// ../../../lib/cpp/$(Configuration);../../../../Boost/lib
//
// Configuration Properties -> Linker -> Input -> Additional Dependencies --
// libthrift.lib
//
// ... adjust relative paths as necessary.
//

#ifdef _WIN32 //thrift is crashing when using boost threads on Mac OSX
#else
#  include <sys/socket.h>
#  include <netinet/in.h>
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Required Includes
//'server' side #includes
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TSimpleServer.h>
//'client' side #includes
#include <thrift/transport/TPipeServer.h>
#include <thrift/transport/TPipe.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransport.h>

#include <thrift/protocol/TBinaryProtocol.h>


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Required Namespaces
//'server' side namespaces
using namespace apache::thrift::server;
using namespace apache::thrift::concurrency;
//common namespaces
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
//using namespace boost; //using ns boost can introduce type conflicts
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

namespace thriftcommon
{
	//----------------------------------------------------------------------------
	//
	//Start the thrift 'server' (both server & client side run one for bidir event signaling)
	// *** This function template will block ***
	//
	template <class MyHandler, class MyProcessor>
	void RunThriftServer (boost::shared_ptr<MyHandler> hndlr, 
		                  int NumThreads, 
						  boost::shared_ptr<TServerTransport> transport,
						  boost::shared_ptr<TServer> &server)
	{
#ifdef _WIN32
		if (!hndlr.get())
			throw std::exception("RunThriftServer() invalid handler");
		if (!transport.get())
			throw std::exception("RunThriftServer() invalid transport");
#else
		if ( !hndlr.get() || !transport.get() )
			throw std::exception();
#endif

		boost::shared_ptr<MyHandler> handler(hndlr);
		boost::shared_ptr<TProcessor> processor(new MyProcessor(handler));
		boost::shared_ptr<TTransportFactory> tfactory(new TBufferedTransportFactory());
		boost::shared_ptr<TProtocolFactory> pfactory(new TBinaryProtocolFactory());

		if(NumThreads <= 1)
		{	//Single-threaded server
			server.reset(new TSimpleServer(processor, transport, tfactory, pfactory));
		}
		else
		{	//Multi-threaded server
			boost::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(NumThreads);
			boost::shared_ptr<ThreadFactory> threadFactory = boost::shared_ptr<ThreadFactory>(new ThreadFactory());
			threadManager->threadFactory(threadFactory);
			threadManager->start();
			server.reset(new TThreadPoolServer(processor, transport, tfactory, pfactory, threadManager));
		}

		printf("Starting the 'server'...\n");
		server->serve();
		printf("done.\n");
	}

	// Thrift server wrapper function that accepts a pipe name.
	// A handler must be passed in to this version.
	template <class MyHandler, class MyProcessor>
	void RunThriftServer (boost::shared_ptr<MyHandler> hndlr, int NumThreads, std::string pipename, boost::shared_ptr<TServer> &svr)
	{
#ifndef _WIN32  //Mac, *nix
		unlink(pipename.c_str());
#endif
		boost::shared_ptr<TServerTransport> transport(new TPipeServer(pipename, 1024, NumThreads)); //Named pipe
		RunThriftServer<MyHandler, MyProcessor>(hndlr, NumThreads, transport, svr);
	}

	// Thrift server wrapper function that accepts a pipe name.
	// This version instantiates its own handler.
	template <class MyHandler, class MyProcessor>
	void RunThriftServer (int NumThreads, std::string pipename)
	{
		boost::shared_ptr<MyHandler> handler(new MyHandler());
		boost::shared_ptr<TServer> server;

		RunThriftServer<MyHandler, MyProcessor>(handler, NumThreads, pipename, server);
	}

	// Thrift server wrapper function that accepts a socket port number.
	// A handler must be passed in to this version.
	template <class MyHandler, class MyProcessor>
	void RunThriftServer (boost::shared_ptr<MyHandler> hndlr, int NumThreads, int Port)
	{
		boost::shared_ptr<TServerTransport> transport(new TServerSocket(Port));
		boost::shared_ptr<TServer> server;
		RunThriftServer<MyHandler, MyProcessor>(hndlr, NumThreads, transport, server);
	}

	// Thrift server wrapper function that accepts a socket port number.
	// This version instantiates its own handler.
	template <class MyHandler, class MyProcessor>
	void RunThriftServer (int NumThreads, int Port)
	{
		boost::shared_ptr<MyHandler> handler(new MyHandler());

		RunThriftServer<MyHandler, MyProcessor>(handler, NumThreads, Port);
	}

	//
	template <class MyHandler, class MyProcessor>
	void RunThriftServer (boost::shared_ptr<MyHandler> hndlr, int NumThreads, boost::shared_ptr<TServerTransport> transport)
	{
		boost::shared_ptr<TServer> server;
		RunThriftServer<MyHandler, MyProcessor>(hndlr, NumThreads, transport, server);
	}

	//----------------------------------------------------------------------------
	//Connect to thrift 'server' - Socket version
	//(both server & client side run one for bidir event signaling)
	//
	template <class MyClient, class MyTransport>
	void ConnectToServer (boost::shared_ptr<MyClient> &client, boost::shared_ptr<MyTransport> &transport, int Port)
	{
		//Client side connection using sockets transport.
		boost::shared_ptr<TTransport> socket(new TSocket("localhost", Port));
		transport.reset(new TBufferedTransport(socket));
		boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

		client.reset(new MyClient(protocol));
	}

	//Connect to thrift 'server' - Named Pipe version
	template <class MyClient, class MyTransport>
	void ConnectToServer (boost::shared_ptr<MyClient> &client, boost::shared_ptr<MyTransport> &transport, std::string pipename)
	{
		//Client side connection using Named Pipe transport.
		boost::shared_ptr<TTransport> pipe(new TPipe(pipename));
		transport.reset(new TBufferedTransport(pipe));
		boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

		client.reset(new MyClient(protocol));
	}

	//Connect to thrift 'server' - Anonymous Pipe version
	//Currently only supported under Windows
#ifdef _WIN32
	template <class MyClient, class MyTransport>
	void ConnectToServer (boost::shared_ptr<MyClient> &client, boost::shared_ptr<MyTransport> &transport, HANDLE RdPipe, HANDLE WrtPipe)
	{
		//Client side connection using sockets transport.
#ifdef _WIN32
		boost::shared_ptr<TTransport> pipe(new TPipe((int)RdPipe, (int)WrtPipe));
		transport.reset(new TBufferedTransport(pipe));
#else
		boost::shared_ptr<TTransport> socket(new TSocket("localhost"));
		transport.reset(new TBufferedTransport(socket));
#endif
		boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));

		client.reset(new MyClient(protocol));
	}
#endif

	//----------------------------------------------------------------------------
	//Launch child process and pass R/W anonymous pipe handles on cmd line.
	//Currently only supported under Windows
#ifdef _WIN32
	bool LaunchAnonPipeChild(std::string app, boost::shared_ptr<TServerTransport> transport);
#endif
}
