/*
 * 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 "serverexchange/session/BasicSession.h"
#include "Logger/LoggerMacroses.h"

using namespace NS_DM_Client;
using namespace NS_DM_Client::NS_Communication;
using namespace NS_DM_Client::NS_SyncMLCommand;

static const char * c_LogName = "BasicSession";

BasicSession::BasicSession(ConnectionInfo &info) :
	Session(info)
{
}


BasicSession::~BasicSession()
{
}


SStatusCommand* BasicSession::CreateSyncHdrStatus(int code, const char * responseURI)
{
	SStatusCommand *status = new SStatusCommand(code);
	status->SetMsgRef(m_connectionInfo.LastServerMessageID());
	status->SetCmdRef("0");
	status->SetCmd("SyncHdr");

	if (m_connectionInfo.devinf.get())
	{
		status->SetTargetRef(m_connectionInfo.devinf->getDevID());
		status->SetSourceRef(responseURI);
	}
	return status;
}


bool BasicSession::IsAuthenticationPassed(Funambol::Status &status0)
{
//	const char *data = "";
//	if (status0.getData())
//		data = status0.getData()->getData();
//	else
//		return false;
//
//	int code = atoi(data);

	return false;
}


bool BasicSession::IsServerCredValid(Funambol::Cred *cred)
{
	bool result = false;

	if (cred && cred->getData() && cred->getFormat() && cred->getType())
	{
		const char *format = cred->getFormat();
		const char *type   = cred->getType();

		if (!strcmp(AUTH_TYPE_BASIC, type) && !strcmp("b64", format))
		{
			Funambol::Authentication auth(AUTH_TYPE_BASIC,
										  m_connectionInfo.acconfig.getServerID(),
										  m_connectionInfo.acconfig.getServerPWD());
			GDLDEBUG("'%s' vs '%s'", cred->getData(), auth.getData())
			result = !strcmp(cred->getData(), auth.getData());
		}
		else
			GDLDEBUG("  failure: wrong type ['%s'] or format ['%s']", format, type);
	}
	else
		GDLDEBUG("cred to check is - %x", cred);

	GDLDEBUG("cred valid: %s [%x]", result ? "true" : "false", cred);
	return result;
}


bool BasicSession::ReadChal(Funambol::Chal &chal)
{
	Funambol::Meta *pMeta  = chal.getMeta();
	if (!pMeta)
		return true;

	const char *type = pMeta->getType();
	GDLDEBUG("Read chal, type %s", type);

	if (!strcmp(AUTH_TYPE_MD5, type) || !strcmp(AUTH_TYPE_MAC, type))
	{
		m_connectionInfo.SwitchToSessionType(type);
		GDLDEBUG("Switch to session type: %s", type);

		const char *b64NextNoce = NULL;
		if (pMeta->getNextNonce())
		{
			b64NextNoce = pMeta->getNextNonce()->getValueAsBase64();
			m_connectionInfo.acconfig.setClientNonce(b64NextNoce);
			SAFE_DELETE_ARR(b64NextNoce);
		}
	}

	return true;
}


const char * BasicSession::GetTypeName()
{
	return AUTH_TYPE_BASIC;
}


void BasicSession::insertSessionInitiationCommands(int code)
{
	GDLDEBUG("m_firstMessage %d", m_firstMessage);
	if (m_firstMessage)
	{
		insertAlertReplace(code);
		m_firstMessage = false;
	}

	//	if (m_commandsAreResent)
	//	{
	//		// pass RespURI to this place - !!
	//		GDLDEBUG("Post status command to continue communication");
	////		SStatusCommand *status =
	////			m_pSession->CreateSyncHdrStatus(INVALID_CREDENTIALS, m_pSyncML->getSyncHdr()->getRespURI());
	////		m_serverExchange.AddCommand(SCommandPtr(status));
	//	}
}
