/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */


#include "NotificationStub.h"
#include "ClientAdapter/ClientAdapterStub.h"
#include "CommonUtils.h"
#include "ClientAdapter/INotificationUpdater.h"
#include "daemon/INotification.h"

#include "Logger/Logger.h"
#include "Logger/LoggerMacroses.h"
#include "Message.h"
#include "common/Utils.h"

namespace NS_DM_Client
{
	NotificationStub::NotificationStub(ClientAdapterStub& clientAdapterStub):
		m_clientAdapterStub(clientAdapterStub)
	{

	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::Add(MsgType notifType, size_t msgId)
	{
		RegisteredRequests::iterator found = m_registeredRequests.find(notifType);
		if (found == m_registeredRequests.end())
		{
			Requests requests;
			requests.push_back(msgId);
			m_registeredRequests[notifType] = requests;
		}
		else
		{
			found->second.push_back(msgId);
		}
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::Clear()
	{
		m_registeredRequests.clear();
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::sendResponse(MsgType msgType, MsgSubType subType, bool removeMsg, const String& data/* = ""*/)
	{
		NS_Logging::Logger& m_logger = NS_Logging::GetLogger("NotificationStub");
		LOG_DEBUG_(m_logger, "MsgType = %s, sybtype = %s, removeMsg = %d, data = '%s'", 
			S_msgTypeDescription[msgType], S_msgSubTypeDescription[subType], removeMsg, data.c_str());

		RegisteredRequests::iterator found = m_registeredRequests.find(msgType);
		if (found == m_registeredRequests.end())
		{
			LOG_ERROR_(m_logger, "Msg is not found", msgType, subType, removeMsg, data.c_str());
			return;
		}

		Requests& requests = found->second;
		for (size_t i = 0; i != requests.size(); ++i)
		{
			Message response;
			response.m_id = requests[i];
			response.m_type = msgType;
			response.m_subType = subType;
			if (!data.empty())
			{
				StringToBytes(data, response.m_data);
			}
			if (removeMsg)
			{
				requests.erase(requests.begin() + i);
				--i;
			}
			LOG_DEBUG_(m_logger, "Sending response %d", i);
			m_clientAdapterStub.sendResponse(response);
		}
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::SessionAborted()
	{
		sendResponse(e_notifyDMSession, e_none, true, S_notificationStatusDescription[e_aborted]);
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::SessionStarted(bool isSuccessful)
	{
		String data = isSuccessful? "true": "false";
		sendResponse(e_startDMSession, e_none, true, data);
		sendResponse(e_notifyDMSession, e_none, false, S_notificationStatusDescription[e_started]);
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::SessionFinished()
	{
		sendResponse(e_notifyDMSession, e_none, false, S_notificationStatusDescription[e_finished]);
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::CheckFirmwareUpdate(bool isNewFirmware)
	{
		String data = isNewFirmware? S_true: S_false;
		sendResponse(e_checkFirmwareUpdate, e_none, false, data);
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::FirmwareUpdateStart(FirmwareUpdate::EnumFirmwareOperation fwo)
	{
		MsgSubType subType = s_mapFirmwareOperation(fwo);
		sendResponse(e_notifyFirmwareUpdate, subType, false, S_notificationStatusDescription[e_started]);
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::FirmwareUpdateFinished(FirmwareUpdate::EnumFirmwareOperation fwo)
	{
		MsgSubType subType = s_mapFirmwareOperation(fwo);
		sendResponse(e_notifyFirmwareUpdate, subType, false, S_notificationStatusDescription[e_finished]);
	}
	//-------------------------------------------------------------------------------------------

	MsgSubType NotificationStub::s_mapFirmwareOperation(FirmwareUpdate::EnumFirmwareOperation fwo)
	{
		MsgSubType subType = e_none;
		switch (fwo)
		{
		case FirmwareUpdate::e_Download:
			subType = e_FirmwareDownload;
			break;

		case FirmwareUpdate::e_Update:
			subType = e_FirmwareUpdate;
			break;

		case FirmwareUpdate::e_DownloadAndUpdate:
			subType = e_FirmwareDownloadAndUpdate;
			break;

		case FirmwareUpdate::e_Error:
			subType = e_none;
			break;
		}

		return subType;
	}
	//-------------------------------------------------------------------------------------------

	void NotificationStub::ProvisioningUpdate(const char* URI)
	{
		String data = (URI) ? URI : "";
		NS_Logging::Logger& m_logger = NS_Logging::GetLogger("NotificationStub");
		LOG_DEBUG_(m_logger, "URI = '%s'", data.c_str());
		sendResponse(e_notifyProvisioningUpdate, e_none, false, data);
	}

	void NotificationStub::StartDRMDCollecting(int duration)
	{
		String data = ToString(duration);
		NS_Logging::Logger& m_logger = NS_Logging::GetLogger("NotificationStub");
		LOG_DEBUG_(m_logger, "Duration = '%s'", data.c_str());
		sendResponse(e_collectDRMD, e_none, false, data);
	}
}

