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

#include "EncryptedStartupSettings.h"
#include "LqrSMACLoadSaveBoostXml.h"
#include "PayloadMessage.h"
#include "nsextend.h"
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>

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

namespace LiquidRobotics {
namespace EncryptedStartup {

EncryptedStartupSettings::EncryptedStartupSettings()
: boardAddress(0x2000)
//, dateVerb("")
, description("SMC/Encrypted")
, deviceType(136)
, echoedAcksRequested(false)
, eventsRequested(false)
, firmwareMajor(0)
, firmwareMinor(0)
, firmwareRev(1)
, pollingRate(15)
, powerNotificationRequested(true)
, powerOffDelay(60)
, powerOnDelay(0)
, serialNum("000000")
, serverName("EncryptedStartup")
, shutdownVerb("sudo shutdown -h now")
, portSettings("/dev/ttyS2", ISerialPort::BAUD_115200, ISerialPort::PARITY_NONE, ISerialPort::CHAR_SIZE_8,
				ISerialPort::STOP_BITS_2, ISerialPort::FLOW_CONTROL_NONE, true, true, 1.0f)
, telemetryRequested(false)
{
}

EncryptedStartupSettings::~EncryptedStartupSettings()
{
}

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

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

const string& EncryptedStartupSettings::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 EncryptedStartupSettings::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& EncryptedStartupSettings::GetDescription() const
{
	return description;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

void EncryptedStartupSettings::Load(const string& fileName)
{
	LoadBoostXml(fileName, *this);
}

void EncryptedStartupSettings::Save(const string& fileName) const
{
	SaveBoostXml(fileName, *this);
}

}
}
