/*
 * 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 <boost/test/unit_test.hpp>
#include "ClientAdapter/ClientAdapterStub.h"
#include "../clientadapterproxy/ClientAdapterProxy.h"

#include "MockFIFOWrapper.h"
#include "ManagementObjects/DevInfo.h"
#include "Common.h"
#include "../../treemanager/UTestMOTree/MockDataStorage.h"
#include "MessageDeserializer.h"
#include "MessageSerializer.h"
#include "Message.h"
#include "daemon/NotificationCenter.h"

BOOST_AUTO_TEST_CASE(TestGetTNDS)
{
	std::cout << "START: TestGetTNDS" << std::endl;
	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));
	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	// put message into fifo (simulate proxy)
	std::string tndsDevInfo;
	FillDevInfoAsTnds(tndsDevInfo);

	BOOST_CHECK(clientAdapterStub.Start()); // read request message and put response to outFifo queue (inFIFOWrapper)
	Wait();

	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_get, NS_DM_Client::e_none);
	Wait();

	BOOST_CHECK(clientAdapterStub.Stop());

	// check fifo's queue count after
	NS_DM_Client::MockFIFOWrapper& outFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper);
	NS_DM_Client::MockFIFOWrapper& inFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper);
	BOOST_CHECK(outFIFOWrapper.GetMessagesCount() == 0);
	BOOST_CHECK(inFIFOWrapper.GetMessagesCount() == 2);

	TearDown();
	std::cout << "END: TestGetTNDS" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(TestSetTNDS)
{
	std::cout << "START: TestSetTNDS" << std::endl;
	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));
	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	// put message into fifo (simulate proxy)
	std::string tndsDevInfo;
	FillDevInfoAsTnds(tndsDevInfo);

	BOOST_CHECK(clientAdapterStub.Start()); // read request message and put response to outFifo queue (inFIFOWrapper)
	Wait();

	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_set, NS_DM_Client::e_none, tndsDevInfo);
	Wait();

	BOOST_CHECK(clientAdapterStub.Stop());

	// check fifo's queue count after
	NS_DM_Client::MockFIFOWrapper& outFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper);
	NS_DM_Client::MockFIFOWrapper& inFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper);
	BOOST_CHECK(outFIFOWrapper.GetMessagesCount() == 0);
	BOOST_CHECK(inFIFOWrapper.GetMessagesCount() == 2);

	TearDown();
	std::cout << "END: TestSetTNDS" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(CheckProvisionUpdateStub)
{
	std::cout << "START: CheckProvisionUpdateStub" << std::endl;
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));

	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	// simulate request 
	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_checkProvision, NS_DM_Client::e_none);

	BOOST_CHECK(clientAdapterStub.Start()); 
	Wait();

	S_notificationCenter->SessionStarted(true);
	Wait();

	NS_DM_Client::MockFIFOWrapper& inFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper);
	BOOST_CHECK(inFIFOWrapper.GetMessagesCount() == 3); // 1 - status response, 2,3 - response

	BOOST_CHECK(clientAdapterStub.Stop());
	TearDown();
	std::cout << "END: CheckProvisionUpdateStub" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(SwitchClientProfile)
{
	std::cout << "START: SwitchClientProfile" << std::endl;
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));

	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_set, NS_DM_Client::e_clientProfileName, "DefaultProfile");

	BOOST_CHECK(clientAdapterStub.Start()); 
	Wait();

	NS_DM_Client::MockFIFOWrapper& inFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper);
	BOOST_CHECK(inFIFOWrapper.GetMessagesCount() == 1);

	BOOST_CHECK(clientAdapterStub.Stop());
	TearDown();
	std::cout << "END: SwitchClientProfile" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(GetClientProfilesStub)
{
	std::cout << "START: GetClientProfilesStub" << std::endl;
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));

	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	// simulate request 
	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_clientProfiles, NS_DM_Client::e_none);

	BOOST_CHECK(clientAdapterStub.Start()); 
	Wait();

	NS_DM_Client::MockFIFOWrapper& inFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper);
	BOOST_CHECK(inFIFOWrapper.GetMessagesCount() == 4);

	BOOST_CHECK(clientAdapterStub.Stop());
	TearDown();
	std::cout << "END: GetClientProfilesStub" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(ReceiveTwoRequests)
{
	std::cout << "START: ReceiveTwoRequests" << std::endl;
	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));
	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	BOOST_CHECK(clientAdapterStub.Start());
	Wait(10000);

	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_open, NS_DM_Client::e_none);
	SimulateRequest(S_outFIFOWrapper, 2, NS_DM_Client::e_close, NS_DM_Client::e_none);
	Wait(10000);

	NS_DM_Client::MockFIFOWrapper& inFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper);
	BOOST_CHECK(inFIFOWrapper.GetMessagesCount() == 2);

	BOOST_CHECK(clientAdapterStub.Stop());
	TearDown();
	std::cout << "END: ReceiveTwoRequests" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(ReadSetDevInfoRequest)
{
	std::cout << "START: ReadSetDevInfoRequest" << std::endl;
	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));
	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	// put message into fifo (simulate proxy)
	NS_DM_Client::DevInfo deviceInfo;
	deviceInfo.m_DevId = "devId";
	deviceInfo.m_Man = "Man";
	deviceInfo.m_Mod = "Mod";
	deviceInfo.m_DmV = "DmV";
	deviceInfo.m_Lang = "Lang";
	std::string deviceInfoXml;
	deviceInfo.Serialize(deviceInfoXml);

	BOOST_CHECK(clientAdapterStub.Start()); // read request message and put response to outFifo queue (inFIFOWrapper)
	Wait();

	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_get, NS_DM_Client::e_devInfo, deviceInfoXml);
	Wait();

	BOOST_CHECK(clientAdapterStub.Stop());

	// check fifo's queue count after
	NS_DM_Client::MockFIFOWrapper& outFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper);
	NS_DM_Client::MockFIFOWrapper& inFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper);
	BOOST_CHECK(outFIFOWrapper.GetMessagesCount() == 0);
	BOOST_CHECK(inFIFOWrapper.GetMessagesCount() == 2);

	TearDown();
	std::cout << "END: ReadSetDevInfoRequest" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(StartClientAdapterStub)
{
	std::cout << "START: StartClientAdapterStub" << std::endl;
	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();

	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper);
	BOOST_CHECK(clientAdapterStub.Start());
	BOOST_CHECK(clientAdapterStub.Stop());

	TearDown();
	std::cout << "END: StartClientAdapterStub" << std::endl;
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(ReadGetDevInfoRequest)
{
	std::cout << "START: ReadGetDevInfoRequest" << std::endl;
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_inFIFOWrapper)); 
	NS_DM_Client::ClearFIFO(dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper));

	NS_DM_Client::ClientAdapterStub clientAdapterStub(*S_configuration);
	clientAdapterStub.Init();
	NS_DM_Client::SetFIFOWrappers(clientAdapterStub, S_outFIFOWrapper, S_inFIFOWrapper); // outgoing queue for stub = incoming queue for proxy

	BOOST_CHECK(clientAdapterStub.Start()); // read request message and put response to outFifo queue
	Wait();

	// put message into fifo with a help of proxy
	SimulateRequest(S_outFIFOWrapper, 1, NS_DM_Client::e_get, NS_DM_Client::e_devInfo);
	Wait();

	// check fifo's queue count after
	NS_DM_Client::MockFIFOWrapper& outFIFOWrapper = dynamic_cast<NS_DM_Client::MockFIFOWrapper&>(*S_outFIFOWrapper);
	BOOST_CHECK(outFIFOWrapper.GetMessagesCount() == 0);

	BOOST_CHECK(clientAdapterStub.Stop());
	TearDown();
	std::cout << "END: ReadGetDevInfoRequest" << std::endl;
}
//-------------------------------------------------------------------------------------------
