/*
 * 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".
 */

/* $Id$ */

#include "Logger.h"
#include "DeviceAdapter/IDeviceAdapter.h"
#include "DeviceAdapter/DeviceUpdater.h"
#include "DevInfo.h"
#include "DevDetail.h"
#include "DMAcc.h"
#include "WiMAX.h"
#include "WiMAXSupp.h"
#include "Root.h"

namespace NS_DM_Client
{
	const char S_pathSeperator = '/';

	DeviceUpdater::DeviceUpdater(IDeviceAdapter& deviceAdapter): m_deviceAdapter(deviceAdapter), m_logger(NS_Logging::GetLogger("DeviceUpdater"))
	{
		m_isAdapterOpened = m_deviceAdapter.Open();
		if (!m_isAdapterOpened)
		{
			LOG_WARNING_(m_logger, "Failed to open device");
		}
	}
	//-------------------------------------------------------------------------------------------
	DeviceUpdater::~DeviceUpdater()
	{
		if (m_isAdapterOpened)
		{
			m_deviceAdapter.Close();
		}
	}
	//-------------------------------------------------------------------------------------------
	bool DeviceUpdater::Execute(const String& path, IMOTreeManager& treeManager)
	{
		if (!m_isAdapterOpened)
		{
			LOG_WARNING_(m_logger, "Device is not open. Nothing for Execute");
			return true;
		}

		bool res = true;
		// detect structure
		LOG_(m_logger, "Trying to detect structure to execute");
		size_t firstSlash = path.find_first_of(S_pathSeperator); // find first slash after root "./"
		if (firstSlash != String::npos)
		{
			size_t secondSlash = path.find_first_of(S_pathSeperator, firstSlash + sizeof(S_pathSeperator));
			if (secondSlash != String::npos)
			{
				String structName = path.substr(firstSlash + sizeof(S_pathSeperator), secondSlash - firstSlash - sizeof(S_pathSeperator));
				LOG_(m_logger, "Structure is detected = %s", structName.c_str());
				if (structName == MORootFieldName[e_DevInfo])
				{
					DevInfo devInfo;
					res = res && devInfo.Deserialize(treeManager);
					LOG_(m_logger, "Structure DevInfo was deserialized, res = %d", res);
					res = res && m_deviceAdapter.SetDeviceInfo(devInfo);
				}
				else if (structName == MORootFieldName[e_DevDetail])
				{
					DevDetail devDetail;
					res = res && devDetail.Deserialize(treeManager);
					LOG_(m_logger, "Structure DevDetail was deserialized, res = %d", res);
					res = res && m_deviceAdapter.SetDeviceDetail(devDetail);
				}
				else if (structName == MORootFieldName[e_DMAcc])
				{
					DMAcc dmAcc;
					res = res && dmAcc.Deserialize(treeManager);
					LOG_(m_logger, "Structure DMAcc was deserialized, res = %d", res);
					res = res && m_deviceAdapter.SetDMAccount(dmAcc);
				}
				else if (structName == MORootFieldName[e_WiMAX])
				{
					WiMAX wimax;
					res = res && wimax.Deserialize(treeManager);
					LOG_(m_logger, "Structure WiMAX was deserialized, res = %d", res);
					res = res && m_deviceAdapter.SetWiMAX(wimax);
				}
				else if (structName == MORootFieldName[e_WiMAXSupp])
				{
					WiMAXSupp wimaxSupp;
					res = res && wimaxSupp.Deserialize(treeManager);
					LOG_(m_logger, "Structure WiMAXSupp was deserialized, res = %d", res);
					res = res && m_deviceAdapter.SetWiMAXSupp(wimaxSupp);
				}
			}
		}
		return res;
	}
	//-------------------------------------------------------------------------------------------
	bool DeviceUpdater::Synchronize(IMOTreeManager& treeManager)
	{
		if (!m_isAdapterOpened)
		{
			LOG_WARNING_(m_logger, "Device is not open. Nothing for Synchronize");
			return true;
		}
		DevInfo devInfo;
		bool res = m_deviceAdapter.GetDeviceInfo(devInfo);
		res = res && devInfo.Serialize(treeManager);

		DevDetail devDetail;
		res = res && m_deviceAdapter.GetDeviceDetail(devDetail);
		res = res && devDetail.Serialize(treeManager);

		DMAcc dmAccount;
		res = res && m_deviceAdapter.GetDMAccount(dmAccount);
		res = res && dmAccount.Serialize(treeManager);

		WiMAX wimax;
		res = res && m_deviceAdapter.GetWiMAX(wimax);
		res = res && wimax.Serialize(treeManager);

		WiMAXSupp wimaxSupp;
		res = res && m_deviceAdapter.GetWiMAXSupp(wimaxSupp);
		res = res && wimaxSupp.Serialize(treeManager);

		LOG_(m_logger, "Synchronization with device finished, res = %d", res);
		return res;
	}
	//-------------------------------------------------------------------------------------------
}
