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

#include "../Node.h"
#include <iostream>
#include "Common.h"
#include "MockDataStorage.h"
#include "commontypes.h"

//const std::string S_root;
using namespace NS_DM_Client;

namespace fs = boost::filesystem;

//-------------------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(CreateLeaf)
{
	URI uri = "CreateLeaf/Node1/Node2";
	NS_DM_Client::Node leaf(uri, S_dataStorage);
	fs::path path(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri).c_str(), fs::native);

	BOOST_CHECK(!fs::exists(path));

	leaf.SetContent("some content");
	BOOST_CHECK(fs::exists(path));

    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath());
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(CreateProperties)
{
	URI uri = "CreateProperties/Node1/Node2";
	NS_DM_Client::Node leaf(uri, S_dataStorage);
	fs::path path(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri).c_str(), fs::native);

	leaf.SetProperty(NS_DM_Client::e_verNo, "version1");
	BOOST_CHECK(fs::exists(path));

    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath());
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(GetContentForInteriorNode)
{
	URI uri = "GetContentForInteriorNode/Node1/Node2";
	fs::path path(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri).c_str(), fs::native);
	NS_DM_Client::Node node(uri, S_dataStorage);
	node.SetProperty(NS_DM_Client::e_format, "node");

	String realContent;
	//std::cout << "Before GetContent: node = " << &node << std::endl;
	BOOST_CHECK(!node.GetContent(realContent));

    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath());
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(GetContent)
{
	URI uri = "GetContent/Node1/Node2";
	NS_DM_Client::Node leaf(uri, S_dataStorage);
	fs::path path(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri).c_str(), fs::native);

	String content("some content");
	leaf.SetContent(content.c_str());
	leaf.SetProperty(NS_DM_Client::e_format, "chr");
	BOOST_CHECK(fs::exists(path));

	URI realContent;
	BOOST_CHECK(leaf.GetContent(realContent));
	//std::cout << "realContent = " << realContent << std::endl;
	BOOST_CHECK(content == realContent);

    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath());
}

//-------------------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(GetProperty)
{
	URI uri = "GetProperty/Node1/Node2";
	NS_DM_Client::Node leaf(uri, S_dataStorage);
	fs::path path(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri).c_str(), fs::native);

	String property("version1");
	leaf.SetProperty(NS_DM_Client::e_verNo, property.c_str());
	BOOST_CHECK(fs::exists(path));

	URI realProperty;
	leaf.GetProperty(NS_DM_Client::e_verNo, realProperty);
	//std::cout << "realProperty = " << realProperty << std::endl;
	BOOST_CHECK(property == realProperty);

    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath());
}
//-------------------------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(CheckIsLeaf)
{
	URI uri = "CheckIsLeaf/Node1/Node2";
	fs::path path(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri).c_str(), fs::native);

	NS_DM_Client::Node node(uri, S_dataStorage);
	std::string property("node");
	node.SetProperty(NS_DM_Client::e_format, property.c_str());
	BOOST_CHECK(fs::exists(path));
	BOOST_CHECK(!node.IsLeaf());
	fs::remove_all(path.parent_path());

	NS_DM_Client::Node leaf(uri, S_dataStorage);
	property = "chr";
	node.SetProperty(NS_DM_Client::e_format, property.c_str());
	BOOST_CHECK(fs::exists(path));
	BOOST_CHECK(node.IsLeaf());

    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath());
}
//-------------------------------------------------------------------------------------------
// TODO: add test GetUnexistingProperty
BOOST_AUTO_TEST_CASE(GetNodeChildrenList)
{
	URI uri1 = "GetNodeChildrenList/Node1/Node1_1";
	URI uri2 = "GetNodeChildrenList/Node1/Node1_2";
	NS_DM_Client::Node node1(uri1, S_dataStorage);
	NS_DM_Client::Node node2(uri2, S_dataStorage);
	fs::path path1(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri1).c_str());
	fs::path path2(String(NS_DM_Client::NS_DataStorage::GetBasePath() + (String)"/"
	    + c_testProfile + (String)"/" + uri2).c_str());

	// create property to force saving to storage
	node1.SetProperty(NS_DM_Client::e_verNo, "version1");
	node2.SetProperty(NS_DM_Client::e_verNo, "version1");
	BOOST_CHECK(fs::exists(path1));
	BOOST_CHECK(fs::exists(path2));

	NS_DM_Client::Node::ChildrenPaths expectedChildrenPaths;
	expectedChildrenPaths.push_back("Node1_1");
	expectedChildrenPaths.push_back("Node1_2");
	NS_DM_Client::Node::ChildrenPaths realChildrenPaths;
	NS_DM_Client::Node parentNode("GetNodeChildrenList/Node1", S_dataStorage);
	parentNode.GetChildren(realChildrenPaths);
	//std::cout << "realChildren = " << realChildrenPaths[0] << " " << realChildrenPaths[1] << std::endl;
	BOOST_CHECK((expectedChildrenPaths[0] == realChildrenPaths[0]) || (expectedChildrenPaths[0] == realChildrenPaths[1])
		|| (expectedChildrenPaths[1] == realChildrenPaths[1]) || (expectedChildrenPaths[1] == realChildrenPaths[0]));

    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath());
}
//------------------------------------------------------------------------------------------


