/*
* Copyright 2009 Funambol, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $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 c_pathSeparator = '/';
    const char* const S_pathSeparator = "/";

    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_pathSeparator); // find first slash after root "./"
        if (firstSlash != String::npos)
        {
            size_t secondSlash = path.find_first_of(S_pathSeparator, firstSlash + sizeof(c_pathSeparator));
            if (secondSlash != String::npos)
            {
                String structName = path.substr(firstSlash + sizeof(c_pathSeparator), secondSlash - firstSlash - sizeof(c_pathSeparator));
                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;
    }
    //-------------------------------------------------------------------------------------------
}
