/*
* 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 "daemon/DaemonEngine.h"
#include "common/Buffer.h"
#include "base/util/StringBuffer.h"
#include "daemon/Configuration.h"
#include "daemon/Profile.h"

#include "syncml/core/Get.h"
#include "syncml/core/Item.h"
#include "syncml/core/Target.h"
#include "Logger/LoggerMacroses.h"

#include "treemanager/MOTreeGetCommandTest.h"
#include "treemanager/MOTreeGetCommand.h"

#include "treemanager/MOTreeExecCommand.h"
#include "treemanager/IMOTreeManager.h"

#include "executionqueue/IExecutionQueue.h"

#include "Event.h"

#include "Errors.h"
#include "serverexchange/commands/RequestFWUCommand.h"

using namespace NS_DM_Client;
using namespace NS_DM_Client::NS_Daemon;

static const char c_LoggerInstanceName[] = "DaemonEngine";

StatusCode DaemonEngine::execute_RequestGetValueFromTreeCommand(const Buffer& input, StatusCode& response_res, Buffer& output)
{
    StatusCode res = e_Failed;

    while (true)
    {
        // parsing input
        char* char_path = (char*)malloc(input.Size() + 1);
        if (char_path)
        {
            memset(char_path, 0, input.Size() + 1);
            memcpy(char_path, input.GetPointer(), input.Size());
        }
        else
        {
            LERROR("Failed allocate memory for tree uri");
            break;
        }

        String path = char_path;
        free(char_path);
        String profile;
        String uri;
        size_t delimiter;
        if ((delimiter = path.find(":")) != String::npos)
        {
            profile = path.substr(0, delimiter);
            uri = path.substr(delimiter + 1);
        }
        else
        {
            LERROR("Failed to find delimiter between profile and uri. Uri format incorrect");
            break;
        }

        // get appropriate profile
        ProfileComponentsHolder* prholder = 0;
        for(int i = 0; i < m_conf.GetProfilesCount(); ++i)
        {
            Profile* p = m_conf.GetProfile(i);
            String pr_name = p->GetName();
            if (p->GetName() == profile)
            {
                if (p->IsEnabled())
                {
                    prholder = p->GetComponentsHolder();
                    break;
                }
                else
                {
                    LERROR("Selected profile not enabled");
                    break;
                }
            }
        }
        if (!prholder)
        {
            LERROR("can't get appropriate profile holder");
	    break;
        }

        // creation
        Funambol::Get* get_command = new Funambol::Get;
        // initialization with URI
        Funambol::Item* item = new Funambol::Item;
        Funambol::ArrayList* items =  new Funambol::ArrayList;
        Funambol::Target* target = new Funambol::Target(uri.c_str(), 0, 0);

        if (get_command && item && items && target)
        {
            item->setTarget(target);
            items->add(*item);
            get_command->setItems(items);
            GetPtr ptr(get_command);

            Buffer result;

            NS_Common::EventEx sigResult;
            MOTreeGetCommandTest* command = new MOTreeGetCommandTest(prholder, ptr, "1", &sigResult, res, output);
            if (prholder->GetExecutionQueue()->Add(*command))
            {
                if (sigResult.wait() == MOTreeGetCommandTest::e_CommandExecuted)
                {
                    response_res = res;
                }
                else
                {
                    LWARN("command was not executed");
                }
            }
            else
            {
                delete command;
            }

            delete target;
            delete items;
            delete item;
        }
        break;
    }

	return res;
}

StatusCode DaemonEngine::execute_RequestFirmwareUpdate(bool userInitiated, const Buffer& input)
{
    StatusCode res = e_Failed;

    while (true)
    {
        // parsing input
        char* char_profile = (char*)malloc(input.Size() + 1);
        if (char_profile)
        {
            memset(char_profile, 0, input.Size() + 1);
            memcpy(char_profile, input.GetPointer(), input.Size());
        }
        else
        {
            LERROR("Failed allocate memory for profile string representation");
            break;
        }

        String profile = char_profile;
        free(char_profile);

        // get appropriate profile
        ProfileComponentsHolder* prholder = 0;
        for(int i = 0; i < m_conf.GetProfilesCount(); ++i)
        {
            Profile* p = m_conf.GetProfile(i);
            String pr_name = p->GetName();
            if (p->GetName() == profile)
            {
                if (p->IsEnabled())
                {
                    prholder = p->GetComponentsHolder();
                    break;
                }
                else
                {
                    LERROR("Selected profile not enabled");
                    break;
                }
            }
        }
        if (!prholder)
        {
            LERROR("can't get appropriate profile holder");
	        break;
        }

        LOG_DEBUG_(NS_Logging::GetLogger(c_LoggerInstanceName), "execute_RequestFirmwareUpdate: BEFORE RequestFWUCommand command creation and queue. User initiated: %s", userInitiated ? "true" : "false");
        NS_Communication::RequestFWUCommand* command = new NS_Communication::RequestFWUCommand(*prholder->GetServerExchangeManager(), userInitiated);
        if (prholder->GetExecutionQueue()->Add(*command))
        {
            LOG_DEBUG_(NS_Logging::GetLogger(c_LoggerInstanceName), "execute_RequestFirmwareUpdate: After RequestFWUCommand command creation and queue - SUCCESS");
            res = e_Ok;
        }
        else
        {
            LOG_DEBUG_(NS_Logging::GetLogger(c_LoggerInstanceName), "execute_RequestFirmwareUpdate: After RequestFWUCommand command creation and queue - FAIL");
            delete command;
        }

        break;
    }

    return res;
}

