/*
 * 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 "DMAcc.h"
#include "Common.h"
#include "treemanager/IMOTreeManager.h"
#include "TNDSMgmtTree/TNDSCreator.h"
#include "TNDSMgmtTree/TNDSExtractor.h"

namespace NS_DM_Client
{
	enum DMAccEnum
	{
		e_AppID = 0,
		e_ServerID,
		e_Name,
		e_PrefConRef,
		e_AAuthPref,
		e_ToConRef,
		e_AppAuth,
		e_AppAddr
	};

	enum DMAccImplEnum
	{
		e_DMAcc = 0
	};

	const String DMAccFieldPath[] =
	{
		"./DMAcc"
	};

 	const String DMAccFieldName[] =
 	{
		"AppID",
		"ServerID",
		"Name",
		"PrefConRef",
		"AAuthPref",
		"ToConRef",
		"AppAuth",
		"AppAddr"
 	};
	//-------------------------------------------------------------------------------------------

	const char* DMAccToConfFieldName[] =
	{
		"ConRef"
	};
	//-------------------------------------------------------------------------------------------

	enum DMAccAppAddrEnum
	{
		e_Addr = 0,
		e_AddrType,
		e_PortNbr
	};

	const char* DMAccAppAddrFieldName[] =
	{
		"Addr",
		"AddrType",
		"PortNbr"
	};
	//-------------------------------------------------------------------------------------------

	enum DMAccAppAuthEnum
	{
		e_AAuthLevel = 0,
		e_AAuthType,
		e_AAuthName,
		e_AAuthSecret,
		e_AAuthData
	};

	const char* DMAccAppAuthFieldName[] =
	{
		"AAuthLevel",
		"AAuthType",
		"AAuthName",
		"AAuthSecret",
		"AAuthData"
	};
	//-------------------------------------------------------------------------------------------

	bool AppAddr::Serialize(const String& basePathName, IMOTreeManager& treeManager) const
	{
		bool res = NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAddrFieldName[e_Addr], m_Addr, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAddrFieldName[e_AddrType], m_AddrType, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAddrFieldName[e_PortNbr], m_PortNbr, treeManager);
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool AppAddr::Deserialize(const String& basePathName, IMOTreeManager& treeManager)
	{
		bool res = NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAddrFieldName[e_Addr], m_Addr, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAddrFieldName[e_AddrType], m_AddrType, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAddrFieldName[e_PortNbr], m_PortNbr, treeManager);
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool AppAddr::Serialize(const String& basePathName, TNDSCreator& tree) const
	{
		tree.Append(basePathName, DMAccAppAddrFieldName[e_Addr], m_Addr);
		tree.Append(basePathName, DMAccAppAddrFieldName[e_AddrType], m_AddrType);
		tree.Append(basePathName, DMAccAppAddrFieldName[e_PortNbr], m_PortNbr);
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool AppAddr::Deserialize(const String& basePathName, TNDSExtractor& tree)
	{
		tree.GetValue(basePathName, DMAccAppAddrFieldName[e_Addr], m_Addr);
		tree.GetValue(basePathName, DMAccAppAddrFieldName[e_AddrType], m_AddrType);
		tree.GetValue(basePathName, DMAccAppAddrFieldName[e_PortNbr], m_PortNbr);
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool AppAuth::Serialize(const String& basePathName, IMOTreeManager& treeManager) const
	{
		bool res = NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthLevel], m_AAuthLevel, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthType], m_AAuthType, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthName], m_AAuthName, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthSecret], m_AAuthSecret, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthData], m_AAuthData, treeManager);
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool AppAuth::Deserialize(const String& basePathName, IMOTreeManager& treeManager)
	{
		bool res = NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthLevel], m_AAuthLevel, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthType], m_AAuthType, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthName], m_AAuthName, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthSecret], m_AAuthSecret, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccAppAuthFieldName[e_AAuthData], m_AAuthData, treeManager);
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool AppAuth::Serialize(const String& basePathName, TNDSCreator& tree) const
	{
		tree.Append(basePathName, DMAccAppAuthFieldName[e_AAuthLevel], m_AAuthLevel);
		tree.Append(basePathName, DMAccAppAuthFieldName[e_AAuthType], m_AAuthType);
		tree.Append(basePathName, DMAccAppAuthFieldName[e_AAuthName], m_AAuthName);
		tree.Append(basePathName, DMAccAppAuthFieldName[e_AAuthSecret], m_AAuthSecret);
		tree.Append(basePathName, DMAccAppAuthFieldName[e_AAuthData], m_AAuthData);
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool AppAuth::Deserialize(const String& basePathName, TNDSExtractor& tree)
	{
		tree.GetValue(basePathName, DMAccAppAuthFieldName[e_AAuthLevel], m_AAuthLevel);
		tree.GetValue(basePathName, DMAccAppAuthFieldName[e_AAuthType], m_AAuthType);
		tree.GetValue(basePathName, DMAccAppAuthFieldName[e_AAuthName], m_AAuthName);
		tree.GetValue(basePathName, DMAccAppAuthFieldName[e_AAuthSecret], m_AAuthSecret);
		tree.GetValue(basePathName, DMAccAppAuthFieldName[e_AAuthData], m_AAuthData);
		return true;
	}
	//-------------------------------------------------------------------------------------------

	bool DMAccImpl::Serialize(const String& basePathName, IMOTreeManager& treeManager) const
	{
		bool res = NS_DM_Client::Serialize(basePathName + S_slash + DMAccFieldName[e_AppID], m_AppID, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccFieldName[e_ServerID], m_ServerID, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccFieldName[e_Name], m_Name, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccFieldName[e_PrefConRef], m_PrefConRef, treeManager);
		res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccFieldName[e_AAuthPref], m_AAuthPref, treeManager);

		// ToConRef
		for (size_t i = 0; i != m_ToConRef.size(); ++i)
		{
			res &= NS_DM_Client::Serialize(basePathName + S_slash + DMAccFieldName[e_ToConRef] + S_slash + ToString(i) + S_slash + 
				DMAccToConfFieldName[0], m_ToConRef[i], treeManager);
		}

		// AppAddr
		for (size_t i = 0; i != m_AppAddr.size(); ++i)
		{
			res &= m_AppAddr[i].Serialize(basePathName + S_slash + DMAccFieldName[e_AppAddr] + S_slash + ToString(i), treeManager);
		}

		// AppAuth
		for (size_t i = 0; i != m_AppAuth.size(); ++i)
		{
			res &= m_AppAuth[i].Serialize(basePathName + S_slash + DMAccFieldName[e_AppAuth] + S_slash + ToString(i), treeManager);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool DMAccImpl::Deserialize(const String& basePathName, IMOTreeManager& treeManager)
	{
		bool res = NS_DM_Client::Deserialize(basePathName + S_slash + DMAccFieldName[e_AppID], m_AppID, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccFieldName[e_ServerID], m_ServerID, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccFieldName[e_Name], m_Name, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccFieldName[e_PrefConRef], m_PrefConRef, treeManager);
		res &= NS_DM_Client::Deserialize(basePathName + S_slash + DMAccFieldName[e_AAuthPref], m_AAuthPref, treeManager);

		// ToConRef
		size_t i = 0;
		String uri(basePathName + S_slash + DMAccFieldName[e_ToConRef] + S_slash + ToString(i) + S_slash + DMAccToConfFieldName[0]);
		while (treeManager.Exist(uri))
		{
			String item;
			res &= NS_DM_Client::Deserialize(uri, item, treeManager);
			m_ToConRef.push_back(item);
			uri = basePathName + S_slash + DMAccFieldName[e_ToConRef] + S_slash + ToString(++i) + S_slash + DMAccToConfFieldName[0];
		}

		// AppAddr
		i = 0;
		uri = basePathName + S_slash + DMAccFieldName[e_AppAddr] + S_slash + ToString(i);
		while (treeManager.Exist(uri))
		{
			AppAddr item;
			res &= item.Deserialize(uri, treeManager);
			m_AppAddr.push_back(item);
			uri = basePathName + S_slash + DMAccFieldName[e_AppAddr] + S_slash + ToString(++i);
		}

		// AppAuth
		i = 0;
		uri = basePathName + S_slash + DMAccFieldName[e_AppAuth] + S_slash + ToString(i);
		while (treeManager.Exist(uri))
		{
			AppAuth item;
			res &= item.Deserialize(uri, treeManager);
			m_AppAuth.push_back(item);
			uri = basePathName + S_slash + DMAccFieldName[e_AppAuth] + S_slash + ToString(++i);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool DMAccImpl::Serialize(const String& basePathName, TNDSCreator& tree) const
	{
		tree.Append(basePathName, DMAccFieldName[e_AppID], m_AppID);
		tree.Append(basePathName, DMAccFieldName[e_ServerID], m_ServerID);
		tree.Append(basePathName, DMAccFieldName[e_Name], m_Name);
		tree.Append(basePathName, DMAccFieldName[e_PrefConRef], m_PrefConRef);
		tree.Append(basePathName, DMAccFieldName[e_AAuthPref], m_AAuthPref);

		// ToConRef
		bool res = true;
		for (size_t i = 0; i != m_ToConRef.size(); ++i)
		{
			tree.Append(basePathName + S_slash + DMAccFieldName[e_ToConRef], ToString(i));
			tree.Append(basePathName + S_slash + DMAccFieldName[e_ToConRef] + S_slash + ToString(i), 
				DMAccToConfFieldName[0], m_ToConRef[i]);
		}

		// AppAddr
		for (size_t i = 0; i != m_AppAddr.size(); ++i)
		{
			tree.Append(basePathName + S_slash + DMAccFieldName[e_AppAddr], ToString(i));
			res &= m_AppAddr[i].Serialize(basePathName + S_slash + DMAccFieldName[e_AppAddr] + S_slash + ToString(i), tree);
		}

		// AppAuth
		for (size_t i = 0; i != m_AppAuth.size(); ++i)
		{
			tree.Append(basePathName + S_slash + DMAccFieldName[e_AppAuth], ToString(i));
			res &= m_AppAuth[i].Serialize(basePathName + S_slash + DMAccFieldName[e_AppAuth] + S_slash + ToString(i), tree);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool DMAccImpl::Deserialize(const String& basePathName, TNDSExtractor& tree)
	{
		tree.GetValue(basePathName, DMAccFieldName[e_AppID], m_AppID);
		tree.GetValue(basePathName, DMAccFieldName[e_ServerID], m_ServerID);
		tree.GetValue(basePathName, DMAccFieldName[e_Name], m_Name);
		tree.GetValue(basePathName, DMAccFieldName[e_PrefConRef], m_PrefConRef);
		tree.GetValue(basePathName, DMAccFieldName[e_AAuthPref], m_AAuthPref);

		// ToConRef
		String uri(basePathName + S_slash + DMAccFieldName[e_ToConRef]);
		m_ToConRef.resize(tree.GetCount(uri));
		for (size_t i = 0; i != m_ToConRef.size(); ++i)
		{
			tree.GetValue(uri + S_slash + ToString(i), DMAccToConfFieldName[0], m_ToConRef[i]);
		}

		// AppAddr
		uri = basePathName + S_slash + DMAccFieldName[e_AppAddr];
		m_AppAddr.resize(tree.GetCount(uri));
		bool res = true;
		for (size_t i = 0; i != m_AppAddr.size(); ++i)
		{
			res &= m_AppAddr[i].Deserialize(uri + S_slash + ToString(i), tree);
		}

		// AppAuth
		uri = basePathName + S_slash + DMAccFieldName[e_AppAuth];
		m_AppAuth.resize(tree.GetCount(uri));
		for (size_t i = 0; i != m_AppAuth.size(); ++i)
		{
			res &= m_AppAuth[i].Deserialize(uri + S_slash + ToString(i), tree);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------


	bool DMAcc::Serialize(IMOTreeManager& treeManager) const
	{
		bool res = true;
		for (size_t i = 0; i != m_DMAccImpl.size(); ++i)
		{
			res = m_DMAccImpl[i].Serialize(DMAccFieldPath[e_DMAcc] + S_slash + ToString(i), treeManager);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool DMAcc::Deserialize(IMOTreeManager& treeManager)
	{
		bool res = true;
		size_t i = 0;
		String uri(DMAccFieldPath[e_DMAcc] + S_slash + ToString(i));
		while (treeManager.Exist(uri))
		{
			DMAccImpl dmAccImpl;
			res &= dmAccImpl.Deserialize(uri, treeManager);
			m_DMAccImpl.push_back(dmAccImpl);
			uri = DMAccFieldPath[e_DMAcc] + S_slash + ToString(++i);
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool DMAcc::Serialize(String& xml) const
	{
		bool res = true;
		TNDSCreator tree;
		for (size_t i = 0; i != m_DMAccImpl.size(); ++i)
		{
			tree.Append(DMAccFieldPath[e_DMAcc], ToString(i));
			res &= m_DMAccImpl[i].Serialize(DMAccFieldPath[e_DMAcc] + S_slash + ToString(i), tree);
		}
		tree.Get(xml);
		return res;
	}
	//-------------------------------------------------------------------------------------------

	bool DMAcc::Deserialize(const String& xml)
	{
		TNDSExtractor tree(xml);
		bool res = true;
		String uri(DMAccFieldPath[e_DMAcc]);
		m_DMAccImpl.resize(tree.GetCount(uri));
		for (size_t i = 0; i != m_DMAccImpl.size(); ++i)
		{
			res &= m_DMAccImpl[i].Deserialize(uri + S_slash + ToString(i), tree);
		}
		return res;
	}

}
