/*
* 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$ */

#include "RequestMessageHandler.h"
#include "ClientAdapter/IRequestHandler.h"

#include "Logger/Logger.h"
#include "Logger/LoggerMacroses.h"

#include "ClientAdapter/IRequestHandler.h"

#include "lock.h"

static const char * const c_LogName = "ClientMessageHandler";
#define LOG_INFO_ NS_Logging::FunctionNameLogHelper(__FUNCTION__, NS_Logging::e_info).Log

namespace NS_DM_Client
{
	// IResponseCallback implementation
	class ConfirmationMessageResponseCallback : public IResponseCallback
	{
	public:
		ConfirmationMessageResponseCallback(String& message, ResponseCode& response, NS_Common::Event& event) 
			: m_message(message), m_responce(response), m_event(event)
		{
		}
		
		virtual void operator()(void* pContext, const String& message, ResponseCode response)
		{
			GDLINFO("FUNCTION STARTED");

			m_message = message;
			m_responce = response;

			m_event.signal();

			GDLINFO("FUNCTION STOPPED");
		}

	private:
		String& m_message;
		ResponseCode& m_responce;		
		NS_Common::Event& m_event;
	};

	RequestMessageHandler::RequestMessageHandler(IRequestHandler* requestHandler) 
		: m_requestHandler(requestHandler)
	{
	}
	
	RequestMessageHandler::~RequestMessageHandler()
	{
	}

	bool RequestMessageHandler::Init()
	{
		return true;
	}
	
	bool RequestMessageHandler::Release()
	{
		m_waitEvent.signal();	
		NS_Common::Lock lock(m_critSection); // wait while confirmation finish
				
		delete this;
		return true;
	}

	StatusCode RequestMessageHandler::Display(const char* message, long min_time, long max_time)
	{
		// no implementation
		return e_Failed;
	}
	
	StatusCode RequestMessageHandler::Confirmation(const char* message, long min_time, long max_time)
	{
		GDLINFO("FUNCTION STARTED");

		NS_Common::Lock lock(m_critSection); 

		String msg;
		ResponseCode resp;

		ConfirmationMessageResponseCallback callback(msg, resp, m_waitEvent); 
		
		m_requestHandler->SendRequest(message, &callback);
		
		GDLINFO("start waiting responce code");
		m_waitEvent.wait();
		GDLINFO("event signalled. We have responce code");

		StatusCode res;
		if (resp != e_ClientStop)
		{
			if (msg.compare(message) != 0)
			{
				GDLERROR("input and output comfirmation messages are not identical");
				return e_Failed;
			}

			switch (resp)
			{
			case e_Yes:
				res = e_Ok;	
				break;
			case e_No:
				res = e_OperationCancelled;
				break;
			default:
				res = e_Failed; 
				break;
			};
		}
		else
		{
			res = e_Stop;		
		}
		
		GDLINFO("FUNCTION STOPPED");
		return res;
	}
	
	StatusCode RequestMessageHandler::UserInput(const char* message, long min_time, long max_time, char*& input,
		long max_len, bool echo_password)
	{
		// no implementation
		return e_Failed;
	}
	
	StatusCode RequestMessageHandler::UserChoice(const char* message, long min_time, long max_time,
		const char* avialable_choise_set, char*& choise_set, bool allowMultipleChoises)
	{
		// no implementation
		return e_Failed;
	}
	
	StatusCode RequestMessageHandler::ProgressNotification(const char* message, long min_time, long max_time, long size_to_download)
	{
		// no implementation
		// should not be forwarded over ClientAdapter
		return e_Ok;
	}

	void RequestMessageHandler::ReleaseString(char* str)
	{
		// no implementation		
	}
}
