/*
 * 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 <syncml/core/Delete.h>
#include <syncml/core/Item.h>
#include <syncml/core/Source.h>

#include "commontypes.h"
#include "Errors.h"
#include "executionqueue/IExecutionQueue.h"
#include "Logger/Logger.h"
#include "Logger/LoggerMacroses.h"
#include "treemanager/MOTreeDeleteCommand.h"
#include "treemanager/IMOTreeManager.h"

const char* const c_LogName = "MOTreeDeleteCommand";

#define LOG_INFO_ NS_Logging::FunctionNameLogHelper(__FUNCTION__, NS_Logging::e_info).Log

using namespace NS_DM_Client;


MOTreeDeleteCommand::MOTreeDeleteCommand(ProfileComponentsHolder* prholder,
										 DeletePtr& cmd,
										 const String& msgID,
                                        const char* serverId)
    : MOTreeItemisedCommand(prholder, cmd, msgID, serverId), m_DeleteCommand(cmd)
{
    if(cmd.get() == NULL)
    {
        GDLWARN("cmd is NULL");
    }
}


MOTreeDeleteCommand::~MOTreeDeleteCommand(void)
{
}


bool MOTreeDeleteCommand::Execute()
{
    GDLINFO("FUNCTION STARTED");

    bool res = m_pProfile && m_DeleteCommand.get();
    if (res)
    {
		res = false;
		m_resCode = performOperation();
		res = InvokeResult();
    }
    else
    {
        GDLERROR("component holder or command instanse not valid");
    }

    GDLINFO("FUNCTION END. Res: %d", res);
    return res;
}


StatusCode MOTreeDeleteCommand::performOperation()
{
    StatusCode res = e_Ok;
    Funambol::ArrayList* items = m_DeleteCommand.get()->getItems();
    if (items)
    {
        IMOTreeManager* treeManager = m_pProfile ? m_pProfile->GetMOTreeManager() : 0;
        if (!treeManager)
        {
            GDLERROR("can't get tree manager instance");
            return e_Failed;
        }

        if (notifyProvisionUpdate(e_Delete, e_sessionStart, e_Ok))
        {
            if (treeManager->StartTransaction() == e_Ok)
            {
                if ((res = processDeleteOnMultipleItems(items, treeManager)) == e_Ok)
                {
                    if ((res = treeManager->Commit()) != e_Ok)
                    {
                        GDLERROR("commit for successfull addition failed");
                    }
                }

                if (res != e_Ok)
                {
                    if (!treeManager->Rollback())
                    {
                        GDLERROR("rollback for unsuccessfull addition failed");
                    }
                }
            }
            else
            {
                GDLERROR("can't start transaction");
                res = e_Failed;
            }
        }
        else
        {
            GDLERROR("NotifyProvisionUpdate failed");
            res = e_Failed;
        }

        if (!notifyProvisionUpdate(e_Delete, e_sessionEnd, res))
        {
            GDLERROR("NotifyProvisionUpdate failed");
        }
    }
    else
    {
        GDLERROR("get items from ItemizedCommand failed");
    }
    return res;
}

StatusCode MOTreeDeleteCommand::processDeleteOnMultipleItems(Funambol::ArrayList* items, IMOTreeManager* treeManager)
{
    StatusCode res = e_Failed;

    Funambol::Item* item = 0;
    int count = items->size();

    for (int i = 0; i < count; ++i)
    {
        if ((item = static_cast<Funambol::Item*> ((*items)[i])) != 0)
        {
            if ( (res = m_pProfile->GetMOTreeManager()->Delete(item->getTarget()->getLocURI(), m_serverID)) != e_Ok)
            {
                GDLERROR("delete item from MO Tree Manager failed");
                break;
            }
        }
        else
        {
            GDLDEBUG("casting to Funambol::Item failed");
            res = e_Failed;
            break;
        }
    }


    return res;
}

Funambol::ArrayList* MOTreeDeleteCommand::getListOfItems()
{
    return m_DeleteCommand->getItems();
}

