/*
 * 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 <syncml/core/TagNames.h>
#include <Utils.h>
#include "treemanager/TreeLocations.h"
#include "serverexchange/wrappers/SCommandFactory.h"
#include "serverexchange/wrappers/SCommandAdapter.h"
#include "serverexchange/wrappers/SAlertCommand.h"
#include "serverexchange/wrappers/SReplaceCommand.h"
#include "serverexchange/wrappers/SResultsCommand.h"
#include "serverexchange/wrappers/SStatusCommand.h"


using namespace NS_DM_Client;
using namespace NS_DM_Client::NS_SyncMLCommand;


static void addItem(Funambol::ArrayList & items, const char * uri, const char * value)
{
	Funambol::ComplexData complexData(value);

	Funambol::Meta meta;
	meta.setFormat("chr");
	meta.setType(TEXT_PLAIN_ENCODING);

	Funambol::Source source(uri);
	Funambol::Item item(NULL, &source, &meta, &complexData, false);

	items.add(item);
}


SAlertCommandPtr SCommandFactory::CreateAlert(const AlertCode alertCode)
{
	return SAlertCommandPtr(new SAlertCommand(alertCode));
}


SAlertCommandPtr SCommandFactory::CreateAlert(const AlertCode alertCode, const char * itemsource, const char *itemdata)
{
	SAlertCommand *pAlert = new SAlertCommand(alertCode);
	pAlert->Prepare();

	Funambol::Item item;
	Funambol::Source src(itemsource);
	Funambol::ComplexData cdata(itemdata);
	item.setData(&cdata);
	item.setSource(&src);
	pAlert->AddItem(item);

	return SAlertCommandPtr(pAlert);
}



SAlertCommandPtr SCommandFactory::CreateAlertOnFWDownload(int result, ExecPtr &exec, const char *alertType)
{
	SAlertCommand *pAlert = new SAlertCommand(AC_GENERIC_ALERT);
	pAlert->Prepare();
	if (exec.get())
	{
		Funambol::Alert *pa = pAlert->GetAlert();
		if (pa)
		{
			pa->setCorrelator(exec->getCorrelator());

			char buffer[16] = {0};
			Funambol::Item       item;
			Funambol::ArrayList *items = exec->getItems();
			if (items && items->size())
			{
				Funambol::Item* pFirstItem = (Funambol::Item*)items->get(0);
				const char *srcuri = NULL;
				if (pFirstItem && pFirstItem->getTarget() )
					srcuri = pFirstItem->getTarget()->getLocURI();

				if (srcuri)
				{
					Funambol::Source source(srcuri);
					item.setSource(&source);
				}
				__sprintf(buffer, "%d", result);
			}
			else
			{
				__sprintf(buffer, "%d", e_Failed);
			}

			Funambol::Meta meta;
			meta.setType(alertType);
			item.setMeta(&meta);

			Funambol::ComplexData data(buffer);
			item.setData(&data);
			pAlert->AddItem(item);
		}
	}

	return SAlertCommandPtr(pAlert);
}

SAlertCommandPtr SCommandFactory::CreateGenericAlert(const char *srcuri, const char *reqtype, int data)
{
	return CreateAlert(AC_GENERIC_ALERT, srcuri, reqtype, data);
}

SAlertCommandPtr SCommandFactory::CreateAlert(const AlertCode acode, const char *srcuri, const char *reqtype, int data)
{
	SAlertCommand *pAlert = new SAlertCommand(acode);
	pAlert->Prepare();

	Funambol::Item item;
	if (srcuri) {
		Funambol::Source source(srcuri);
		item.setSource(&source);
	}

	Funambol::Meta meta;
	meta.setFormat("text/plain");
	meta.setType(reqtype);
	item.setMeta(&meta);
	
	if (data)
	{
		char buffer[64] = {0};
		__sprintf(buffer, "%d", data);
		Funambol::ComplexData data(buffer);
		item.setData(&data);
	}
	pAlert->AddItem(item);

	return SAlertCommandPtr(pAlert);
}


SStatusCommandPtr SCommandFactory::CreateStatus(StatusCode data)
{
	return SStatusCommandPtr(new SStatusCommand(data));
}


SStatusCommandPtr SCommandFactory::CreateStatus(StatusCode data, AbstractCommandPtr &ptrCommand)
{
//	SStatusCommand *pStatus = new SStatusCommand(data, ptrCommand);
//	pStatus->SetOriginatedCommand(ptrCommand);
//	if (ptrCommand.get())
//	{
//		pStatus->SetCmd(ptrCommand->getName());
//		if (ptrCommand.get()->getCmdID())
//			pStatusMessage->SetCmdRef(ptrCommand.get()->getCmdID()->getCmdID());
//	}

	return SStatusCommandPtr(new SStatusCommand(data, ptrCommand));
}


SStatusCommandPtr SCommandFactory::CreateStatus(StatusCode data, Funambol::AbstractCommand &cmd)
{
	SStatusCommand *pStatusMessage = new SStatusCommand(data);
	pStatusMessage->SetCmd(cmd.getName());
	if (cmd.getCmdID())
		pStatusMessage->SetCmdRef(cmd.getCmdID()->getCmdID());

	return SStatusCommandPtr(pStatusMessage);
}


SResultsCommandPtr SCommandFactory::CreateResult(Funambol::ItemizedCommand &cmd, Funambol::ArrayList &results, const char *msgref)
{
	SResultsCommand *pResults = new SResultsCommand();
	if (msgref)
		pResults->SetMsgRef(msgref);

	if (cmd.getCmdID())
		pResults->SetCmdRef(cmd.getCmdID()->getCmdID());

	for (int i=0; i<results.size(); ++i)
	{
		Funambol::Item *pItem = (Funambol::Item*)results.get(i);
		if (pItem)
		{
			pResults->AddResult(pItem->getTarget()  ?  pItem->getTarget()->getLocURI() : NULL,
								pItem->getData()    ?  pItem->getData()->getData()     : NULL,
								pItem->getMeta()    ?  pItem->getMeta()->getFormat()   : NULL,
								pItem->getMeta()    ?  pItem->getMeta()->getType()     : NULL);
		}
	}

	return SResultsCommandPtr(pResults);
}


SCommandPtr SCommandFactory::CreateReplaceDevInf(Funambol::DevInf & devInf)
{
	SReplaceCommand *replace = new SReplaceCommand();
	replace->Prepare();

	Funambol::Replace *pReplace = replace->GetReplace();
	if (pReplace)
	{
		Funambol::ArrayList		items;
		addItem(items, DI_DEVID, devInf.getDevID());
//// 2011.05.24
////		addItem(items, DI_DMV,   devInf.getLang());
		addItem(items, DI_DMV,   devInf.getDmV());
		addItem(items, DI_LANG,  devInf.getLang());
		addItem(items, DI_MAN,   devInf.getMan());
		addItem(items, DI_MOD,   devInf.getMod());

		pReplace->setItems(&items);
	}

	return SCommandPtr(replace);
}
