/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2006-2013  Georg Rudoy
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **********************************************************************/

#include "syncdeltagenerator.h"
#include "core.h"

namespace LeechCraft
{
namespace Aggregator
{
	Sync::Payloads_t SyncDeltaGenerator::GetFeedAdded (Feed_ptr feedPtr)
	{
		Sync::Payloads_t result;

		Sync::Payload fp;
		{
			QDataStream ostr (&fp.Data_, QIODevice::WriteOnly);
			ostr << static_cast<quint16> (PTFeedAdded);
			Feed feed (*feedPtr);
			feed.FeedID_ = FixFeedID (feed.FeedID_);
			ostr << feed;
		}
		result << fp;

		return result;
	}

	Sync::Payloads_t SyncDeltaGenerator::GetChanAdded (Channel_ptr channelPtr)
	{
		Sync::Payloads_t result;

		Sync::Payload item;

		{
			QDataStream ostr (&item.Data_, QIODevice::WriteOnly);
			ostr << static_cast<quint16> (PTChanAdded);
			Channel channel (*channelPtr);
			channel.ChannelID_ = FixChanID (channel.ChannelID_);
			channel.FeedID_ = FixFeedID (channel.FeedID_);
			ostr << channel;
		}

		result << item;

		return result;
	}

	Sync::Payloads_t SyncDeltaGenerator::GetItemAdded (Item_ptr srcItemPtr)
	{
		Sync::Payloads_t result;

		Sync::Payload item;

		{
			QDataStream ostr (&item.Data_, QIODevice::WriteOnly);
			ostr << static_cast<quint16> (PTItemAdded);
			Item srcItem (*srcItemPtr);
			srcItem.ItemID_ = FixItemID (srcItem.ItemID_);
			srcItem.ChannelID_ = FixChanID (srcItem.ChannelID_);
			ostr << srcItem;
		}

		result << item;

		return result;
	}

	Sync::Payloads_t SyncDeltaGenerator::GetChannelTagsChanged (Channel_ptr, const QStringList&)
	{
		// TODO
		return Sync::Payloads_t ();
	}

	void SyncDeltaGenerator::ParseDelta (const Sync::Payload& delta)
	{
		QDataStream istr (delta.Data_);
		quint16 action = 0;
		istr >> action;

		switch (action)
		{
		case PTFeedAdded:
		{
			Feed_ptr feed (new Feed);
			istr >> *feed;
			if (!Remote2LocalFeeds_.contains (feed->FeedID_))
			{
				IDType_t newID = Core::Instance ().GetStorageBackend ()->GetHighestID (PTFeed);
				Remote2LocalFeeds_ [feed->FeedID_] = newID;
			}
			feed->FeedID_ = Remote2LocalFeeds_ [feed->FeedID_];

			feeds_container_t feeds;
			feeds.push_back (feed);
			Core::Instance ().AddFeeds (feeds, QString ());
			break;
		}
		default:
			qWarning () << Q_FUNC_INFO
					<< "unknown action"
					<< action;
			return;
		}
	}

	IDType_t SyncDeltaGenerator::FixFeedID (IDType_t id)
	{
		return Remote2LocalFeeds_.key (id, id);
	}

	IDType_t SyncDeltaGenerator::FixChanID (IDType_t id)
	{
		return Remote2LocalChannels_.key (id, id);
	}

	IDType_t SyncDeltaGenerator::FixItemID (IDType_t id)
	{
		return Remote2LocalItems_.key (id, id);
	}
}
}
