//-------------------------------------------------------------------------------------------------
// <copyright file="ServerExec.h" company="LiquidRobotics">
//  Copyright (c) Liquid Robotics Corporation, confidential and proprietary.  All rights reserved. 
// </copyright>
//
// <summary>
// Declaration for the program class for the ServerExec module
// </summary>
//
// <owner>Mike Cookson</owner>
//-------------------------------------------------------------------------------------------------

#ifndef __SERVEREXEC_H__
#define __SERVEREXEC_H__

#include "ServerExecSettings.h"
#include "EventBase.h"
#include "EventTransceiver.h"
#include "LqrSMACObjectBroker.h"
#include "LqrSMACSemaphore.h"
#include "PayloadManagerClient.h"
#include <cstdio>
#include <ostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>

namespace LiquidRobotics {
namespace SMACFramework {
	class ByteArray;
}
}

class ServerExecProgram : public boost::noncopyable
{
public:

	typedef CORBA::Any Any;
	typedef LiquidRobotics::SMACFramework::ByteArray ByteArray;
	typedef LiquidRobotics::EventLib::IEventBase IEventBase;
	typedef LiquidRobotics::EventLib::EventTransceiver EventTransceiver;
	typedef LiquidRobotics::SMACFramework::ObjectBroker ObjectBroker;
	typedef boost::shared_ptr<ObjectBroker> ObjectBrokerPtr;
	typedef std::ostream ostream;
	typedef LiquidRobotics::EventLib::PayloadManagerClient PayloadManagerClient;
	typedef boost::shared_ptr<PayloadManagerClient> PayloadManagerClientPtr;
	typedef std::string string;
	typedef std::vector<string> StringArray;
	typedef boost::signals2::scoped_connection ScopedConnection;
	typedef boost::shared_ptr<ScopedConnection> ScopedConnectionPtr;
	typedef LiquidRobotics::SMACFramework::Semaphore Semaphore;

	ServerExecProgram(int argc, char* argv[]);

	int Run();

private:

	bool CanPassAsString(const ByteArray& data) const;
	string Collect(FILE* fp);
	void CommandCompleteHandler(EventTransceiver& sender, const IEventBase& receivedEvent);
	void CatFile(const string& fileName, ostream& stm);
	unsigned ConvertAddress(const string& inputStr);
	void DecodeResult(const Any& result, ostream& stm);
	int ExecuteCommand(const string& serverName, const string& commandContent, double timeoutVal, bool timeoutSpec, bool enableAsynchronousResponse = true);
	int ExecuteLocalCommand(const string& serverName, const string& commandContent, bool enableAsynchronousResponse = true);
	int ExecuteRemoteCommand(int remoteAddr, const string& commandContent, double timeoutVal);
	static double GetCurrentTime();
	void InitObjectBroker();
	int ListServers();
	void LoadSettings();
	int Ping(const string& serverName);
	int PingWait(const string& serverName, double timeoutVal);
	void QueueShutdown(int exitCode);
	void Run2();
	void SetArgs(int argc, char* argv[]);
	void ShowUsage(ostream& stm);
	bool ValidateRemote(const string& serverName, unsigned& remoteAddr);
	string ValidateTranslateServerName(const string& serverName);

	string progName;
	bool orbInitialized;
	const size_t maxCommandSize;
	ServerExecSettings settings;
	string serverName;
	StringArray args;
	ObjectBrokerPtr brokerPtr;
	EventTransceiver::Ptr eventTransPtr;
	string action;
	string eventTag;
	int queuedExitCode;
	PayloadManagerClientPtr pmClient;
	ScopedConnectionPtr connectionToCommandCompleteEvent;
	Semaphore commandCompleteSem;
	CORBA::Object_ptr serverPtr;
};

#endif
