//-----------------------------------------------------------------------------------------
// <copyright file="PayloadAddressableMessageServiceSettings.cpp" company="LiquidRobotics">
//
// Copyright (c) 2014 Liquid Robotics, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// This software is associated with a release.  Liquid Robotics makes no
// representation that the design, interfaces or component distribution will
// remain unchanged in future releases.
//
// </copyright>
//
// <summary>
//   Implementation of PayloadAddressableMessageServiceSettings, a serializable entity
//   that holds the configuration settings for PayloadAddressableMessageService
// </summary>
//
// <owner>Mike Cookson</owner>
//-----------------------------------------------------------------------------------------

#include "PayloadAddressableMessageServiceSettings.h"
#include "LqrSMACLoadSaveBoostXml.h"

using namespace std;
using namespace LiquidRobotics::SMACFramework;
using namespace LiquidRobotics::EventLib;

static const string defaultMessageName = "AddressRoutedMessage";
static const string defaultTypeName = "AddressedPacketEvent";
static const string defaultDomainName = "LiquidR-SMC";

namespace LiquidRobotics {
namespace PayloadInterface {

PayloadAddressableMessageServiceSettings::PayloadAddressableMessageServiceSettings()
: enableReceiveNameFilter(false)
, enableReceiveTypeFilter(true)
, transmitSettings(defaultMessageName, defaultTypeName, defaultDomainName)
{
	StringPair sp(defaultTypeName, defaultDomainName);
	receiveTypes.insert(sp);
}

PayloadAddressableMessageServiceSettings::~PayloadAddressableMessageServiceSettings()
{
}

const EventSettings& PayloadAddressableMessageServiceSettings::GetTransmitSettings() const
{
	return transmitSettings;
}

bool PayloadAddressableMessageServiceSettings::IsMessageAddressable(const EventSettings& eventIDs) const
{
	const bool nameFiltered = enableReceiveNameFilter && (receiveNames.find(eventIDs.GetName()) == receiveNames.end());
	const StringPair theType(eventIDs.GetTypeName(), eventIDs.GetDomainName());
	const bool typeFiltered = enableReceiveTypeFilter && (receiveTypes.find(theType) == receiveTypes.end());
	bool isAddressable = !nameFiltered && !typeFiltered;
	return isAddressable;
}

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

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

std::ostream& PayloadAddressableMessageServiceSettings::ToStream(std::ostream& stm) const
{
	stm << "enableReceiveNameFilter=" << (enableReceiveNameFilter ? "true" : "false")
	    << " enableReceiveTypeFilter=" << (enableReceiveTypeFilter ? "true" : "false");

	if (enableReceiveNameFilter)
	{
		stm << " receiveNames={";

		bool first = true;

		for (StringSet::const_iterator ci = receiveNames.begin(); ci != receiveNames.end(); ++ci)
		{
			if (first)
				first = false;
			else
				cout << ",";

			stm << " \"" << *ci << "\"";
		}

		stm << " }";
	}

	if (enableReceiveTypeFilter)
	{
		stm << " receiveTypes={";

		bool first = true;

		for (StringPairSet::const_iterator ci = receiveTypes.begin(); ci != receiveTypes.end(); ++ci)
		{
			if (first)
				first = false;
			else
				cout << ",";

			stm << " { \"" << ci->first << "\", \"" << ci->second << "\" }";
		}

		stm << " }";
	}

	stm << " transmitSettings=" << transmitSettings;
	return stm;
}

ostream& operator<<(std::ostream& stm, const PayloadAddressableMessageServiceSettings& settings)
{
	return settings.ToStream(stm);
}

}
}
