#include <boost/test/unit_test.hpp>
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"

#include <iostream>
#include "treemanager/MOTreeManager.h"
#include "../../UTestMOTree/MockDataStorage.h"

#include "Mocks/NotificationCenterMock.h"

#include "serverexchange/wrappers/SCommandAdapter.h"
#include "treemanager/MOTreeAddCommand.h"
#include "treemanager/MOTreeGetCommand.h"

#include <syncml/core/Item.h>
#include <syncml/core/Add.h>
#include <syncml/core/Get.h>

#include "Common.h"
#include "Errors.h"

//------------------------------------------------------------------------------------------------------
using namespace NS_DM_Client;
//------------------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(MOTreeGetCommand_GetWithOneItem_success)
{
    NS_DM_Client::NotificationCenterMock* notify_center =
        dynamic_cast<NS_DM_Client::NotificationCenterMock*>(S_ProfileHolder->GetNotificationCenter());
    notify_center->clearMockData();

    Funambol::ArrayList* items =  new Funambol::ArrayList;

    // create leaf node first
    // creation
    Funambol::Add* add_command = new Funambol::Add;
    Funambol::Item* item = new Funambol::Item;
    Funambol::Target* target = new Funambol::Target("./MOTreeGetCommand_GetWithOneItem_success/Item");
    item->setTarget(target);
    Funambol::ComplexData data("MOTreeGetCommand_GetWithOneItem_success_Item");
    item->setData(&data);
    items->add(*item);

    // main execution
    add_command->setItems(items);
    AddPtr add_ptr(add_command);
    MOTreeAddCommand tree_add_command(S_ProfileHolder, add_ptr, "1", 0);
    BOOST_CHECK(tree_add_command.Execute() == true);

    // now we can check delete command
    notify_center->clearMockData();

    Funambol::Get* get_command = new Funambol::Get;
    get_command->setItems(items);
    GetPtr get_ptr(get_command);
    MOTreeGetCommand tree_get_command(S_ProfileHolder, get_ptr, "1", 0);
    BOOST_CHECK(tree_get_command.Execute() == true);

    // check notifications
    BOOST_CHECK(notify_center->m_mockData.size() == 2); // must be notifications: start and finish
    if (notify_center->m_mockData.size() == 2)
    {
        BOOST_CHECK(notify_center->m_mockData[0].m_URI.compare("./MOTreeGetCommand_GetWithOneItem_success/Item") == 0);
        BOOST_CHECK(notify_center->m_mockData[0].m_command == NS_DM_Client::e_Get);
        BOOST_CHECK(notify_center->m_mockData[0].m_event == NS_DM_Client::e_sessionStart);
        BOOST_CHECK(notify_center->m_mockData[0].m_resultCode == NS_DM_Client::e_Ok);

        BOOST_CHECK(notify_center->m_mockData[1].m_URI.compare("./MOTreeGetCommand_GetWithOneItem_success/Item") == 0);
        BOOST_CHECK(notify_center->m_mockData[1].m_command == NS_DM_Client::e_Get);
        BOOST_CHECK(notify_center->m_mockData[1].m_event == NS_DM_Client::e_sessionEnd);
        BOOST_CHECK(notify_center->m_mockData[1].m_resultCode == NS_DM_Client::e_Ok);
    }

    delete target;
    delete item;

    delete items;
}

BOOST_AUTO_TEST_CASE(MOTreeGetCommand_GetPropertyWithOneItem_success)
{
    NS_DM_Client::NotificationCenterMock* notify_center =
        dynamic_cast<NS_DM_Client::NotificationCenterMock*>(S_ProfileHolder->GetNotificationCenter());
    notify_center->clearMockData();

    Funambol::ArrayList* items =  new Funambol::ArrayList;

    // create leaf node first
    // creation
    Funambol::Add* add_command = new Funambol::Add;
    Funambol::Item* item = new Funambol::Item;
    Funambol::Target* target = new Funambol::Target("./MOTreeGetCommand_GetWithOneItem_success/Item");
    item->setTarget(target);
    Funambol::ComplexData data("MOTreeGetCommand_GetWithOneItem_success_Item");
    item->setData(&data);
    items->add(*item);

    // main execution
    add_command->setItems(items);
    AddPtr add_ptr(add_command);
    MOTreeAddCommand tree_add_command(S_ProfileHolder, add_ptr, "1", 0);
    BOOST_CHECK(tree_add_command.Execute() == true);

    // now we can check delete command
    notify_center->clearMockData();
    items->clear();

    // item for property extraction

    Funambol::Item* item2 = new Funambol::Item;
    Funambol::Target* target2 = new Funambol::Target("./MOTreeGetCommand_GetWithOneItem_success/Item?prop=Type");
    item2->setTarget(target2);
    Funambol::ComplexData data2("MOTreeGetCommand_GetWithOneItem_success_Item");
    item2->setData(&data2);
    items->add(*item2);



    size_t ttt = notify_center->m_mockData.size();

    Funambol::Get* get_command = new Funambol::Get;
    get_command->setItems(items);
    GetPtr get_ptr(get_command);
    MOTreeGetCommand tree_get_command(S_ProfileHolder, get_ptr, "1", 0);
    BOOST_CHECK(tree_get_command.Execute() == true);

    ttt = notify_center->m_mockData.size();

    // check notifications
    BOOST_CHECK(notify_center->m_mockData.size() == 2); // must be notifications: start and finish
    if (notify_center->m_mockData.size() == 2)
    {
        BOOST_CHECK(notify_center->m_mockData[0].m_URI.compare("./MOTreeGetCommand_GetWithOneItem_success/Item?prop=Type") == 0);
        BOOST_CHECK(notify_center->m_mockData[0].m_command == NS_DM_Client::e_Get);
        BOOST_CHECK(notify_center->m_mockData[0].m_event == NS_DM_Client::e_sessionStart);
        BOOST_CHECK(notify_center->m_mockData[0].m_resultCode == NS_DM_Client::e_Ok);

        BOOST_CHECK(notify_center->m_mockData[1].m_URI.compare("./MOTreeGetCommand_GetWithOneItem_success/Item?prop=Type") == 0);
        BOOST_CHECK(notify_center->m_mockData[1].m_command == NS_DM_Client::e_Get);
        BOOST_CHECK(notify_center->m_mockData[1].m_event == NS_DM_Client::e_sessionEnd);
        BOOST_CHECK(notify_center->m_mockData[1].m_resultCode == NS_DM_Client::e_Ok);
    }

    delete target2;
    delete item2;

    delete target;
    delete item;

    delete items;
}
