/*
* Copyright 2009 Funambol, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

#pragma once

#include "commontypes.h"
#include <PortableThread.h>
#include "CritSection.h"

namespace NS_Logging
{
	class Logger;
}

namespace NS_DM_Client
{
	class IFIFOWrapper;
	struct Message;
	class ProfileComponentsHolder;
	class IMgmtObject;
	class NotificationStub;
	class UIRequestHandler;

	namespace NS_Daemon
	{
		class Configuration;
	}

    class Buffer;

	class ClientAdapterStub
	{
		friend class RequestReceiverThread;
		friend class RequestHandlingThread;
		friend class NotificationStub;
		friend class ProvisionSubscribersHolder;
		friend class UIRequestHandler;

		friend void SetFIFOWrappers(ClientAdapterStub& clientAdapterStub, NS_DM_Client::IFIFOWrapper* inFIFOWrapper,
			NS_DM_Client::IFIFOWrapper* outFIFOWrapper); // for tests only

	public:
		static const char* S_LoggerName;
	public:
		ClientAdapterStub(NS_Daemon::Configuration& configuration);
		virtual ~ClientAdapterStub();

		bool Init(const StringMap& settings);
		bool Start(); // start waiting for requests in another thread
		bool Stop(); // stop waiting for requests

	private:
		void receiveRequest();
		bool receiveRequest(Message& request);

		bool restartFifos();
		bool stopRequestReceiverThread();

		IMgmtObject* getMgmtObject(size_t subType);

		bool sendResponse(const Message& response);
		bool sendResponseHelper(const Message& response);
		bool sendClientProfilesResponse(const Message& response);
		void sendConfirmationRequest(const String& message);

	private: 
		// Handlers
		void handleRequest(const Message& request);
		bool handleRequest(const Message& request, Message& response);

		bool handleOpenType(Message& response);
		bool handleCloseType(Message& response);
		bool handleGetType(const Message& request, Message& response);

		bool handleClientProfilesType(const Message& request, Message& response);
		bool handleClientProfileNameType(const Message& request, Message& response);
		bool handleProfileActivationStatusType(const Message& request, Message& response);
		bool handleProfileActivationStatusByServerIDType(const Message& request, Message& response);

		// EMSK
		bool handleSetEMSKType(const Message& request, Message& response);
		bool handleGetEMSKType(const Message& request, Message& response);

		// DeviceID
		bool handleSetDeviceIDType(const Message& request, Message& response);

		// Manufacturer
		bool handleSetManufacturerType(const Message& request, Message& response);

		// Model
		bool handleSetModelType(const Message& request, Message& response);

		// requests with notifications
		bool handleStartDMSessionType(const Message& request, Message& response);
		bool handleStartBootstrapType(const Message& request, Message& response);
		bool handleStartDRMDType(const Message& request, Message& response);
		bool handleDMSessionNotifType(const Message& request, Message& response);
		bool handleChangePasswordType(const Message& request, Message& response);
		bool handleChangePasswordByServerIDType(const Message& request, Message& response);
		bool handleCheckFirmwareUpdateType(const Message& request, Message& response);
		bool handleFirmwareUpdateNotifType(const Message& request, Message& response);
		bool handleProvisioningUpdateNotifType(const Message& request, Message& response);
		bool handleUnsubscribeProvisioningType(const Message& request, Message& response);
		bool handleUnsubscribeNotifType(const Message& request, Message& response);
		bool handleConfirmationRequiredType(const Message& request, Message& response);
		bool handleConfirmationResponseType(const Message& request, Message& response);
		bool handleSetType(const Message& request, Message& response);
		bool handleSetKnownMgmtObject(IMgmtObject& mgmtObject, const Message& request, Message& response);
		bool handleSetUnknownSubType(const Message& request, Message& response);
		bool handleGetKnownMgmtObject(IMgmtObject& mgmtObject, const Message& request, Message& response);
		bool handleGetUnknownSubType(const Message& request, Message& response);
		bool handleNetworkEntry(const Message& request, Message& response);
		bool handleDRMDReady(const Message& request, Message& response);
		bool handleCollectDRMD(const Message& request, Message& response);

		// MessageListener subscriber
		bool needUserInterfaceSubscriber(const StringMap& settings);
	private:
		Thread* m_receiver;
		NS_Daemon::Configuration& m_configuration;
		ProfileComponentsHolder* m_componentHolder;
		IFIFOWrapper* m_inFIFOWrapper; // for incoming messages (inFIFOWrapper for Stub is outFIFOWrapper for Proxy)
		IFIFOWrapper* m_outFIFOWrapper; // for outgoing messages (outFIFOWrapper for Stub is inFIFOWrapper for Proxy)
		NS_Logging::Logger& m_logger;
		NS_Common::CritSection m_criticalSection;
		bool m_stopReceiving;
		NotificationStub* m_notification;
		UIRequestHandler* m_uiRequestHandler; // handle requests from UI
	};
}
