//-------------------------------------------------------------------------------------------------
// <copyright file="OneTimeCommandSettings.cpp" company="LiquidRobotics">
//  Copyright (c) Liquid Robotics Corporation, confidential and proprietary.  All rights reserved. 
// </copyright>
//
// <summary>
// </summary>
//
// <owner></owner>
//-------------------------------------------------------------------------------------------------

#include "OneTimeCommandSettings.h"
#include "PayloadMessage.h"
#include "nsextend.h"
#include <fstream>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>

using namespace std;
using namespace LiquidRobotics::SMACFramework;
using namespace LiquidRobotics::PayloadInterface;

namespace LiquidRobotics {
namespace OneTimeCommand {

#if 0
template<typename T> T ProtectedConvert(const string& val)
{
	T result = 0;

	try
	{
		result = boost::lexical_cast<T>(val);
	}
	catch(...)
	{
	}

	return result;
}
#endif

OneTimeCommandSettings::OneTimeCommandSettings(PayloadMessage::BoardAddress _address, const ByteArray& _message, PayloadMessage::BoardAddress _destination, const string& _portName)
: boardAddress(_address)
//, dateVerb("")
, description("SMC/OneTime")
, deviceType(136)
, echoedAcksRequested(false)
, eventsRequested(false)
, firmwareMajor(0)
, firmwareMinor(0)
, firmwareRev(0)
, pollingRate(15)
, powerNotificationRequested(true)
, powerOffDelay(60)
, powerOnDelay(0)
, serialNum("000000")
, serverName("OneTime")
, shutdownVerb("sudo shutdown -h now")
, portSettings(_portName.c_str(), ISerialPort::BAUD_115200, ISerialPort::PARITY_NONE, ISerialPort::CHAR_SIZE_8,
				ISerialPort::STOP_BITS_2, ISerialPort::FLOW_CONTROL_NONE, true, true, 1.0f)
, telemetryRequested(false)
, destination(_destination)
, message(_message.begin(), _message.end())
{
}

#if 0
string OneTimeCommandSettings::GetSetting(const string& settingName)
{
	ifstream theFile("/home/smc/roots/100_PayloadInterface/PayloadInterface-config.xml");
	string result;

	if (theFile.good())
	{
		string line;
		stringstream startTagStm;
		startTagStm << "<" << settingName << ">";
		string startTag = startTagStm.str();
		stringstream endTagStm;
		endTagStm << "</" << settingName << ">";
		string endTag = endTagStm.str();

		while(theFile.good())
		{
			getline(theFile, line);

			size_t fnd1 = line.find(startTag);

			if (fnd1 != string::npos)
			{
				size_t fnd2 = line.find(endTag, fnd1+startTag.length());

				if (fnd2 != string::npos)
					result = line.substr(fnd1, fnd2);
			}
		}

		theFile.close();
	}

	return result;
}
#endif

OneTimeCommandSettings::~OneTimeCommandSettings()
{
}

OneTimeCommandSettings::PayloadMessage::BoardID OneTimeCommandSettings::GetBoardID() const
{
	return LiquidRobotics::PayloadInterface::GetBoardID(boardAddress);
}

OneTimeCommandSettings::PayloadMessage::BoardAddress OneTimeCommandSettings::GetBoardAddress() const
{
	return boardAddress;
}

const string& OneTimeCommandSettings::GetDateVerb() const
{
	return dateVerb;
}

inline void ReplaceAll(string& io, const string& replacement, const string& pattern)
{
	size_t loc;

	while((loc = io.find(pattern)) != string::npos)
	{
		stringstream newVal;

		if (loc)
			newVal << io.substr(0, loc);

		newVal << replacement;

		const size_t tailStart = loc+pattern.length();

		if (tailStart < io.length())
			newVal << io.substr(tailStart);

		io = newVal.str();
	}
}

string OneTimeCommandSettings::GetDateVerbGMT(int year, int month, int day, int hour, int minute, int second) const
{
	string verb = GetDateVerb();

	ReplaceAll(verb, utos(year, 10, 4), "{yyyy}");
	ReplaceAll(verb, utos(year % 100, 10, 2), "{yy}");
	ReplaceAll(verb, utos(month, 10, 2), "{mm}");
	ReplaceAll(verb, utos(day, 10, 2), "{dd}");
	ReplaceAll(verb, utos(hour, 10, 2), "{HH}");
	ReplaceAll(verb, utos(((hour == 0) || (hour == 12)) ? 12 : (hour % 12), 10, 2), "{hh}");
	ReplaceAll(verb, utos(minute, 10, 2), "{MM}");
	ReplaceAll(verb, utos(second, 10, 2), "{SS}");

	return verb;
}

const string& OneTimeCommandSettings::GetDescription() const
{
	return description;
}

uint16_t OneTimeCommandSettings::GetDeviceType() const
{
	return deviceType;
}

bool OneTimeCommandSettings::GetEchoedAcksRequested() const
{
	return echoedAcksRequested;
}

bool OneTimeCommandSettings::GetEventsRequested() const
{
	return eventsRequested;
}

uint8_t OneTimeCommandSettings::GetFirmwareMajor() const
{
	return firmwareMajor;
}

uint8_t OneTimeCommandSettings::GetFirmwareMinor() const
{
	return firmwareMinor;
}

uint16_t OneTimeCommandSettings::GetFirmwareRev() const
{
	return firmwareRev;
}

uint32_t OneTimeCommandSettings::GetPollingRate() const
{
	return pollingRate;
}

const OneTimeCommandSettings::SerialPortSettings& OneTimeCommandSettings::GetPortSettings() const
{
	return portSettings;
}

bool OneTimeCommandSettings::GetPowerNotificationRequested() const
{
	return powerNotificationRequested;
}

const uint8_t OneTimeCommandSettings::GetPowerOffDelay() const
{
	return powerOffDelay;
}

const uint8_t OneTimeCommandSettings::GetPowerOnDelay() const
{
	return powerOnDelay;
}

const string& OneTimeCommandSettings::GetSerialNum() const
{
	return serialNum;
}

const string& OneTimeCommandSettings::GetServerName() const
{
	return serverName;
}

const string& OneTimeCommandSettings::GetShutdownVerb() const
{
	return shutdownVerb;
}

OneTimeCommandSettings::PayloadMessage::BoardID OneTimeCommandSettings::GetTaskID() const
{
	return LiquidRobotics::PayloadInterface::GetTaskID(boardAddress);
}

bool OneTimeCommandSettings::GetTelemetryRequested() const
{
	return telemetryRequested;
}

const ByteArray& OneTimeCommandSettings::GetMessage() const
{
	return message;
}

PayloadMessage::BoardAddress OneTimeCommandSettings::GetDestination() const
{
	return destination;
}

}
}
