/*
 * Copyright 2010 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$ */

#pragma once

#include <http/TransportAgentFactory.h>
#include "commontypes.h"
#include "serverexchange/CommandStorage.h"
#include "serverexchange/SendingStrategy.h"
#include "serverexchange/session/ISession.h"


namespace NS_DM_Client
{
	class ProfileComponentsHolder;
	
	namespace NS_Communication
	{
		class ConnectionInfo;
		class LOSendingStrategy;
		class ResponseProcessor;

		/// Class implements general communication flow of the dm session
		class Session : public ISession
		{
		public:
			Session(ConnectionInfo &, Funambol::TransportAgent &);
			virtual ~Session();
			
			virtual void Connect(NS_SyncMLCommand::CommandStorage & commands);
			virtual bool IsAuthenticationPassed(Funambol::Status &);
			virtual bool IsResponseValid(const char *, uint resplength);
			virtual bool IsSendingLO();
			virtual void SendMessage(FStringBuffer &);
	
			virtual void SetCommandsSink(NS_SyncMLCommand::ICommandsSink &);
			virtual void SetPCH(ProfileComponentsHolder &);

		protected:
			bool     m_firstMessage;
			bool     m_commandsAreResent;

			ConnectionInfo           &m_connectionInfo;
			Funambol::TransportAgent *m_pTransportAgent;

			NS_SyncMLCommand::CommandStorage m_commands;
			NS_SyncMLCommand::CommandStorage m_commandsToSend;
			ProfileComponentsHolder  *m_pPCH;

			void initializeTransport();
			void checkAcceptTypes();
			void dumpMessage(const char *msg, size_t size, const char *prefix);
			void insertAlertReplace(int code);
			void notifyTransportError();
			void processResponse();
			virtual void insertSessionInitiationCommands(int code) = 0;
			virtual void prepareTransport(const char *, uint);
			virtual void removeEndLineChars(FStringBuffer &);

		private:
			const char        * m_responseMsg;
			LOSendingStrategy * m_pLOStrategy;
			ResponseProcessor * m_pResponseProcessor;
		};
	}
}
