/*
 * 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".
 */


#define BOOST_TEST_MAIN

#include <boost/test/included/unit_test.hpp>
#include <boost/test/unit_test.hpp>
#include "MockFIFOWrapper.h"
#include "MockExecutionQueue.h"
#include "MockMOTreeManager.h"
#include "MockConfiguration.h"
#include "Message.h"
#include "MessageSerializer.h"
#include "daemon/Profile.h"
#include "platform.h"
#include "daemon/NotificationCenter.h"
#include "MockServerExchangeManager.h"

NS_DM_Client::IFIFOWrapper* S_inFIFOWrapper = 0;
NS_DM_Client::IFIFOWrapper* S_outFIFOWrapper = 0;
NS_DM_Client::IExecutionQueue* S_executionQueue = 0;
NS_DM_Client::ProfileComponentsHolder* S_profileHolder = 0;
NS_DM_Client::IMOTreeManager* S_treeManager = 0;
NS_DM_Client::NS_Daemon::Configuration* S_configuration = 0;
NS_DM_Client::NS_Daemon::Profile* S_profile = 0;
NS_DM_Client::INotificationCenter* S_notificationCenter = 0;
NS_DM_Client::IServerExchangeManager* S_serverExchangeManager = 0;

class InitClientAdapter
{
public:
	InitClientAdapter()
	{
// 		_CrtSetBreakAlloc(542);
		S_inFIFOWrapper = new NS_DM_Client::MockFIFOWrapper();
		S_outFIFOWrapper = new NS_DM_Client::MockFIFOWrapper();
		S_executionQueue = new NS_DM_Client::MockExecutionQueue();
		S_profileHolder = new NS_DM_Client::ProfileComponentsHolder();
		S_configuration = new NS_DM_Client::MockConfiguration();
		S_notificationCenter = new NS_DM_Client::NotificationCenter();
		S_serverExchangeManager = new NS_DM_Client::MockServerExchangeManager();
		
		S_profile = new NS_DM_Client::NS_Daemon::Profile();
		S_profile->SetName("DefaultProfile");
		S_profile->SetDescription("DefaultProfileDescription");
		S_profile->SetComponentsHolder(S_profileHolder);

		dynamic_cast<NS_DM_Client::MockConfiguration*>(S_configuration)->AddProfile(S_profile);
		S_treeManager = new NS_DM_Client::MockMOTreeManager();

		S_profileHolder->SetExecutionQueue(S_executionQueue);
		S_profileHolder->SetMOTreeManager(S_treeManager);
		S_profileHolder->SetNotificationCenter(S_notificationCenter);
		S_profileHolder->SetServerExchangeManager(S_serverExchangeManager);
		NS_DM_Client::StringMap settings;
		S_treeManager->Init(settings, "ClientAdapterUnitTests", *S_profileHolder);

		std::cout << "Setup" << std::endl;
	}

	~InitClientAdapter()
	{
		//delete S_profileHolder; it'll be deleted with S_profile
		delete S_inFIFOWrapper;
		delete S_outFIFOWrapper;
		delete S_configuration;
		delete S_profile;
		std::cout << "Teardown" << std::endl;
	}
};

BOOST_GLOBAL_FIXTURE(InitClientAdapter);
//-------------------------------------------------------------------------------------------

void SimulateResponse(NS_DM_Client::IFIFOWrapper* fifoWrapper, size_t msdId, size_t msgType, size_t 
					  msgSubType, const std::string& data/* = ""*/)
{
	NS_DM_Client::Message message(msdId, msgType, msgSubType, data);
	NS_DM_Client::MessageSerializer serializer;
	const NS_DM_Client::MessageSerializer::PlainData& plainData = serializer(message);
	fifoWrapper->Write(&plainData[0], plainData.size());

	NS_DM_Client::MockFIFOWrapper* mockFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper*>(fifoWrapper);
	mockFIFOWrapper->FreezeOff();
}
//-------------------------------------------------------------------------------------------

void SimulateRequest(NS_DM_Client::IFIFOWrapper* fifoWrapper, size_t msdId, size_t msgType, size_t 
					  msgSubType, const std::string& data/* = ""*/)
{
	SimulateResponse(fifoWrapper, msdId, msgType, msgSubType, data);
}
//-------------------------------------------------------------------------------------------

void FreezeOffFIFO(NS_DM_Client::IFIFOWrapper* fifoWrapper)
{
	NS_DM_Client::MockFIFOWrapper* mockFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper*>(fifoWrapper);
	mockFIFOWrapper->FreezeOff();
}
//-------------------------------------------------------------------------------------------

void Wait(int ms/* = 2000*/)
{
#ifdef PLATFORM_WINDOWS
	if (ms == 0)
		::Sleep(INFINITE); // wait while execution completes
	else
		::Sleep(ms); // wait while execution completes
#else
	sleep(10);
#endif
}
//-------------------------------------------------------------------------------------------

void TearDown()
{
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));
}
//-------------------------------------------------------------------------------------------

void FillDevInfoAsTnds(std::string& tndsDevInfo)
{
	tndsDevInfo = std::string(
		"<MgmtTree xmlns='syncml:dmddf1.2'>"
		"<VerDTD>1.2</VerDTD>\n"
		"<Node>"
		"<NodeName>DevId</NodeName>\n"
		"<Path>./DevInfo/</Path>\n"
		"<RTProperties>"
		"<Format>chr</Format>\n"
		"<Value>DevId</Value>\n"
		"</RTProperties>"
		"</Node>"

		"<Node>"
		"<NodeName>Man</NodeName>\n"
		"<Path>./DevInfo/</Path>\n"
		"<RTProperties>"
		"<Format>chr</Format>\n"
		"<Value>Man</Value>\n"
		"</RTProperties>"
		"</Node>"

		"<Node>"
		"<NodeName>Mod</NodeName>\n"
		"<Path>./DevInfo/</Path>\n"
		"<RTProperties>"
		"<Format>chr</Format>\n"
		"<Value>Mod</Value>\n"
		"</RTProperties>"
		"</Node>"

		"<Node>"
		"<NodeName>DmV</NodeName>\n"
		"<Path>./DevInfo/</Path>\n"
		"<RTProperties>"
		"<Format>chr</Format>\n"
		"<Value>DmV</Value>\n"
		"</RTProperties>"
		"</Node>"

		"<Node>"
		"<NodeName>Lang</NodeName>\n"
		"<Path>./DevInfo/</Path>\n"
		"<RTProperties>"
		"<Format>chr</Format>\n"
		"<Value>Lang</Value>\n"
		"</RTProperties>"
		"</Node>"

		"</MgmtTree>"
		); 
}
