/*
 * 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/unit_test.hpp>
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"

#include "../Node.h"
#include <iostream>
#include "treemanager/MOTreeManager.h"
#include "MockDataStorage.h"
#include <syncml/core/Item.h>
#include "Common.h"
#include "Errors.h"

//const std::string S_root;
//const std::string S_workingDirectory("MockMOTree");

namespace fs = boost::filesystem;

BOOST_AUTO_TEST_CASE(GetValueWithSufficientPrivilegeByRootNode)
{
	// add root with ACL = Get=*&Add=*
	std::string uri = "GetValueWithSufficientPrivilegeByRootNode/RootNode";
	NS_DM_Client::Node root(uri, S_dataStorage);
	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
	    + c_testProfile + (NS_DM_Client::String)"/" + uri, fs::native);

	root.SetProperty(NS_DM_Client::e_format, "node");
	root.SetProperty(NS_DM_Client::e_type, "node");
	root.SetProperty(NS_DM_Client::e_ACL, "Get=*");
	BOOST_CHECK(fs::exists(root_path));

    // add child node with empty ACL
	uri = "GetValueWithSufficientPrivilegeByRootNode/RootNode/ChildWithEmptyACL";
	NS_DM_Client::Node leaf(uri, S_dataStorage);
	fs::path leaf_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
	    + c_testProfile + (NS_DM_Client::String)"/" + uri, fs::native);

	std::string content("some content");
	leaf.SetContent(content.c_str());
	leaf.SetProperty(NS_DM_Client::e_format, "chr");
	leaf.SetProperty(NS_DM_Client::e_type, "text/plain");
	leaf.SetProperty(NS_DM_Client::e_ACL, "");
	BOOST_CHECK(fs::exists(leaf_path));


 	Funambol::Item realItem;
	const char* serverId = "someId";
	NS_DM_Client::StatusCode res = S_treeManager->Get(uri, realItem, serverId);
	BOOST_CHECK(res == NS_DM_Client::e_Ok);

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

//
//BOOST_AUTO_TEST_CASE(GetValueWithSufficientPrivilegeByOwnACL)
//{
//	// add root with ACL = Get=*&Add=*
//	std::string uri = "GetValueWithSufficientPrivilegeByOwnACL/RootNode";
//	NS_DM_Client::Node root(uri, S_dataStorage);
//	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
//	    + c_testProfile + (NS_DM_Client::String)"/" + uri, fs::native);
//
//	root.SetProperty(NS_DM_Client::e_format, "node");
//	root.SetProperty(NS_DM_Client::e_type, "node");
//	root.SetProperty(NS_DM_Client::e_ACL, "Get=*&Add=*");
//	BOOST_CHECK(fs::exists(root_path));
//
//    // add child node with empty ACL
//	uri = "GetValueWithSufficientPrivilegeByOwnACL/RootNode/ChildWithEmptyACL";
//	NS_DM_Client::Node leaf(uri, S_dataStorage);
//	fs::path leaf_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
//	    + c_testProfile + (NS_DM_Client::String)"/" + uri, fs::native);
//
//	std::string content("some content");
//	leaf.SetContent(content.c_str());
//	leaf.SetProperty(NS_DM_Client::e_format, "chr");
//	leaf.SetProperty(NS_DM_Client::e_type, "text/plain");
//	leaf.SetProperty(NS_DM_Client::e_ACL, "Add=*&Get=oneId+someId+anotherId&Replace=*&Add=SomeElseId&Get=*&Get=SomeElseId");
//	BOOST_CHECK(fs::exists(leaf_path));
//
// 	Funambol::Item realItem;
//	const char* serverId = "someId";
//	NS_DM_Client::StatusCode res = S_treeManager.Get(uri, realItem, serverId);
//	BOOST_CHECK(res == NS_DM_Client::e_Ok);
//
//    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath() +
//        (NS_DM_Client::String)"/" + c_testProfile + "/GetValueWithSufficientPrivilegeByOwnACL/RootNode");
//}
//
//
//BOOST_AUTO_TEST_CASE(GetValueWithNoSufficientPrivilege)
//{
//	// add root with ACL = Get=*&Add=*
//	std::string uri = "GetValueWithNoSufficientPrivilege/RootNode";
//	NS_DM_Client::Node root(uri, S_dataStorage);
//	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
//	    + c_testProfile + (NS_DM_Client::String)"/" + uri, fs::native);
//
//	root.SetProperty(NS_DM_Client::e_format, "node");
//	root.SetProperty(NS_DM_Client::e_type, "node");
//	root.SetProperty(NS_DM_Client::e_ACL, "Get=*&Add=*");
//	BOOST_CHECK(fs::exists(root_path));
//
//    // add child node with empty ACL
//	uri = "GetValueWithNoSufficientPrivilege/RootNode/ChildWithEmptyACL";
//	NS_DM_Client::Node leaf(uri, S_dataStorage);
//	fs::path leaf_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
//	    + c_testProfile + (NS_DM_Client::String)"/" + uri, fs::native);
//
//	std::string content("some content");
//	leaf.SetContent(content.c_str());
//	leaf.SetProperty(NS_DM_Client::e_format, "chr");
//	leaf.SetProperty(NS_DM_Client::e_type, "text/plain");
//	leaf.SetProperty(NS_DM_Client::e_ACL, "Add=*&Get=oneId+someId+anotherId&Replace=*&Add=SomeElseId&Get=*&Get=SomeElseId");
//	BOOST_CHECK(fs::exists(leaf_path));
//
// 	Funambol::Item realItem;
//	const char* serverId = "noSufficientId";
//	NS_DM_Client::StatusCode res = S_treeManager.Get(uri, realItem, serverId);
//	BOOST_CHECK(res == NS_DM_Client::e_PermissionDenied);
//
//    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath() +
//        (NS_DM_Client::String)"/" + c_testProfile + "/GetValueWithNoSufficientPrivilege/RootNode");
//}
//
//BOOST_AUTO_TEST_CASE(AddValueWithInteriorNodesAndRootWithoutReplaceInACL)
//{
//	// add root with ACL = Get=*&Add=*
//	NS_DM_Client::Node root("AddValueWithInteriorNodesAndRootWithoutReplaceInACL/RootNode", S_dataStorage);
//	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
//	    + c_testProfile + (NS_DM_Client::String)"/" + "AddValueWithInteriorNodesAndRootWithoutReplaceInACL/RootNode", fs::native);
//
//	root.SetProperty(NS_DM_Client::e_format, "node");
//	root.SetProperty(NS_DM_Client::e_type, "node");
//	root.SetProperty(NS_DM_Client::e_ACL, "Get=*&Add=*"); // root without Replace
//	BOOST_CHECK(fs::exists(root_path));
//
//    // add child node
//  	Funambol::Item item;
//	Funambol::Meta meta;
//	meta.setFormat("chr");
//	meta.setType("text/plain");
//	item.setMeta(&meta);
//	std::string oldContent("Some data");
//	item.setData(&Funambol::ComplexData(oldContent.c_str()));
//    NS_DM_Client::StatusCode res = S_treeManager.Add("AddValueWithInteriorNodesAndRootWithoutReplaceInACL/RootNode/InteriorNode1/InteriorNode2/InteriorNode3/ChildWithEmptyACL", item, "www.test_server.com");
//	BOOST_CHECK(res == NS_DM_Client::e_Ok);
//
//    NS_DM_Client::String ACL_value;
//	// check ACL of InteriorNode3
//	NS_DM_Client::Node interior3("AddValueWithInteriorNodesAndRootWithoutReplaceInACL/RootNode/InteriorNode1/InteriorNode2/InteriorNode3", S_dataStorage);
//	BOOST_CHECK(interior3.Exist());
//    BOOST_CHECK(interior3.GetProperty(NS_DM_Client::e_ACL, ACL_value));
//    BOOST_CHECK(ACL_value.empty());
//
//	// check ACL of InteriorNode2
//	NS_DM_Client::Node interior2("AddValueWithInteriorNodesAndRootWithoutReplaceInACL/RootNode/InteriorNode1/InteriorNode2", S_dataStorage);
//	BOOST_CHECK(interior2.Exist());
//    BOOST_CHECK(interior2.GetProperty(NS_DM_Client::e_ACL, ACL_value));
//    BOOST_CHECK(ACL_value.empty());
//
//	// check ACL of InteriorNode1
//	NS_DM_Client::Node interior1("AddValueWithInteriorNodesAndRootWithoutReplaceInACL/RootNode/InteriorNode1", S_dataStorage);
//	BOOST_CHECK(interior1.Exist());
//    BOOST_CHECK(interior1.GetProperty(NS_DM_Client::e_ACL, ACL_value));
//    BOOST_CHECK(ACL_value.compare("Add=www.test_server.com&Get=www.test_server.com&Delete=www.test_server.com&Replace=www.test_server.com") == 0);
//
//    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath() +
//        (NS_DM_Client::String)"/" + c_testProfile + "/AddValueWithInteriorNodesAndRootWithoutReplaceInACL/RootNode");
//}
//
//
//BOOST_AUTO_TEST_CASE(AddValueWithInteriorNodesAndRootWithReplaceInACL)
//{
//	// add root with ACL = Get=*&Add=*&Replace=*
//	NS_DM_Client::Node root("AddValueWithInteriorNodesAndRootWithReplaceInACL/RootNode", S_dataStorage);
//	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
//	    + c_testProfile + (NS_DM_Client::String)"/" + "AddValueWithInteriorNodesAndRootWithReplaceInACL/RootNode", fs::native);
//
//	root.SetProperty(NS_DM_Client::e_format, "node");
//	root.SetProperty(NS_DM_Client::e_type, "node");
//	root.SetProperty(NS_DM_Client::e_ACL, "Get=*&Add=*&Replace=*"); // root with Replace
//	BOOST_CHECK(fs::exists(root_path));
//
//    // add child node
//  	Funambol::Item item;
//	Funambol::Meta meta;
//	meta.setFormat("chr");
//	meta.setType("text/plain");
//	item.setMeta(&meta);
//	std::string oldContent("Some data");
//	item.setData(&Funambol::ComplexData(oldContent.c_str()));
//    NS_DM_Client::StatusCode res = S_treeManager.Add("AddValueWithInteriorNodesAndRootWithReplaceInACL/RootNode/InteriorNode1/InteriorNode2/InteriorNode3/ChildWithEmptyACL", item, "www.test_server.com");
//	BOOST_CHECK(res == NS_DM_Client::e_Ok);
//
//    NS_DM_Client::String ACL_value;
//	// check ACL of InteriorNode3
//	NS_DM_Client::Node interior3("AddValueWithInteriorNodesAndRootWithReplaceInACL/RootNode/InteriorNode1/InteriorNode2/InteriorNode3", S_dataStorage);
//	BOOST_CHECK(interior3.Exist());
//    BOOST_CHECK(interior3.GetProperty(NS_DM_Client::e_ACL, ACL_value));
//    BOOST_CHECK(ACL_value.empty());
//
//	// check ACL of InteriorNode2
//	NS_DM_Client::Node interior2("AddValueWithInteriorNodesAndRootWithReplaceInACL/RootNode/InteriorNode1/InteriorNode2", S_dataStorage);
//	BOOST_CHECK(interior2.Exist());
//    BOOST_CHECK(interior2.GetProperty(NS_DM_Client::e_ACL, ACL_value));
//    BOOST_CHECK(ACL_value.empty());
//
//	// check ACL of InteriorNode1
//	NS_DM_Client::Node interior1("AddValueWithInteriorNodesAndRootWithReplaceInACL/RootNode/InteriorNode1", S_dataStorage);
//	BOOST_CHECK(interior1.Exist());
//    BOOST_CHECK(interior1.GetProperty(NS_DM_Client::e_ACL, ACL_value));
//    BOOST_CHECK(ACL_value.empty());
//
//    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath() +
//        (NS_DM_Client::String)"/" + c_testProfile + "/AddValueWithInteriorNodesAndRootWithReplaceInACL/RootNode");
//}
//
//BOOST_AUTO_TEST_CASE(AddValueWithInteriorNodesAndRootWithoutReplaceInACLAndTryChangeACL)
//{
//	// add root with ACL = Get=*&Add=*
//	NS_DM_Client::Node root("AddValueWithInteriorNodesAndRootWithoutReplaceInACLAndTryChangeACL/Root", S_dataStorage);
//	fs::path root_path(NS_DM_Client::NS_DataStorage::GetBasePath() + (NS_DM_Client::String)"/"
//	    + c_testProfile + (NS_DM_Client::String)"/" + "AddValueWithInteriorNodesAndRootWithoutReplaceInACLAndTryChangeACL/Root", fs::native);
//
//	root.SetProperty(NS_DM_Client::e_format, "node");
//	root.SetProperty(NS_DM_Client::e_type, "node");
//	root.SetProperty(NS_DM_Client::e_ACL, "Get=*&Add=*"); // root with Replace
//	BOOST_CHECK(fs::exists(root_path));
//
//    // add child node
//  	Funambol::Item item;
//	Funambol::Meta meta;
//	meta.setFormat("chr");
//	meta.setType("text/plain");
//	item.setMeta(&meta);
//	std::string oldContent("Some data");
//	item.setData(&Funambol::ComplexData(oldContent.c_str()));
//    NS_DM_Client::StatusCode res = S_treeManager.Add("AddValueWithInteriorNodesAndRootWithoutReplaceInACLAndTryChangeACL/Root/X/FwV", item, "*");
//	BOOST_CHECK(res == NS_DM_Client::e_Ok);
//
//    // try change ACL of node
//    res = S_treeManager.ReplacePropertyValue("AddValueWithInteriorNodesAndRootWithoutReplaceInACLAndTryChangeACL/Root/X/FwV", "ACL", "Add=*&Exec=*&Replace=*&Get=*&Delete=*", "*");
//	BOOST_CHECK(res == NS_DM_Client::e_Ok);
//
//	// check ACL of node
//	NS_DM_Client::String ACL_value;
//	NS_DM_Client::Node leaf("AddValueWithInteriorNodesAndRootWithoutReplaceInACLAndTryChangeACL/Root/X/FwV", S_dataStorage);
//	BOOST_CHECK(leaf.Exist());
//    BOOST_CHECK(leaf.GetProperty(NS_DM_Client::e_ACL, ACL_value));
//    BOOST_CHECK(ACL_value.compare("Add=*&Exec=*&Replace=*&Get=*&Delete=*") == 0);
//
//    fs::remove_all(NS_DM_Client::NS_DataStorage::GetBasePath() +
//        (NS_DM_Client::String)"/" + c_testProfile + "/AddValueWithInteriorNodesAndRootWithoutReplaceInACLAndTryChangeACL/Root");
//}
//
