#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(NotifyProvisionUpdateStub)
{
	std::cout << "START: NotifyProvisionUpdateStub" << 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_notifyProvisionUpdate, 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: NotifyProvisionUpdateStub" << std::endl;
}
//-------------------------------------------------------------------------------------------

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(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_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;
}
//-------------------------------------------------------------------------------------------
