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

#pragma once

#include <spds/AccessConfig.h>
#include <syncml/core/Cred.h>
#include <syncml/core/DevInf.h>
#include "commontypes.h"
#include "serverexchange/MessageProcessingState.h"

namespace NS_DM_Client
{
	namespace NS_Communication
	{
		typedef boost::shared_ptr<Funambol::AccessConfig> AccessConfigPtr;

		typedef struct tagCS {
			size_t MaxObjSize;
			size_t MaxMsgSize;

			bool KeepNewLines;
			bool SSLVerifyHost;
			bool SSLVerifyServer;
			bool UseWBXML;

			String CertificatesLocation;
			String MessagesDumpPath;
			String UserAgentName;

			tagCS() :
				MaxObjSize(0), MaxMsgSize(0), 
				KeepNewLines(true), SSLVerifyHost(false), SSLVerifyServer(false), UseWBXML(false)
			{}

		} ConnectionSettings;
		
		// TODO - use/extend this state struct to store connection's state instead of ConnectionInfo members
		typedef struct tagState {
			bool   abortConnection;
			bool   authenticationFailed;
			bool   connectionFinished;
			bool   hasLOSending;
			bool   hasToResendLastCommands;
			bool   hasToSendNextChunk;
			bool   reconnectInstantly;
			bool   repeatAuthentication;
			String serverLastMessageID;
			
			void Reset() {
				abortConnection = authenticationFailed = false;
				connectionFinished = true;
				hasLOSending = hasToResendLastCommands = hasToSendNextChunk = false;
				reconnectInstantly = repeatAuthentication = false;
			}
			
			tagState() : 
				abortConnection(false), authenticationFailed(false), connectionFinished(true), 
				hasLOSending(false), hasToResendLastCommands(false), hasToSendNextChunk(false), 
				reconnectInstantly(false), repeatAuthentication(false)
			{}
		} ConnectionState;
		
		
		/// Class represents info about current connection with server
		class ConnectionInfo
		{
		public:
			ConnectionSettings     settings;
			ConnectionState        state;
			Funambol::AccessConfig acconfig;
			DevInfPtr              devinf;
			MessageProcessingState msgState;

			ConnectionInfo();
			~ConnectionInfo();

			String appID;
			String prefferedAuth;
			String prefferedConRef;
			String name;
			String accname;


			bool IsAuthenticated() { return m_isAuthenticated; }
			void SetAuthenticated(bool b);

			void ResetMessageID();
			char * GetNextMessageID();

			const char * GetNextNonce();

			bool IsWaitingAuthentication() { return m_isWaitingAuthentication; }
			void SetWaitingAuthentication(bool b);

			bool IsWaitingForNextChunk() { return m_isWaitingForNextChunk; }
			void SetWaitingForNextChunk(bool b) { m_isWaitingForNextChunk = b; }

			bool AllAuthSchemesUsed() { return m_usedAllAuthSchemes; }
			void SetAuthSchemeSwitched(bool b) { m_usedAllAuthSchemes = b; }

			const char * LastServerMessageID() { return m_lastServerMessageID; }
			void SetLastServerMessageID(const char *theID);

			const char * NextChunkAlertCmdID() { return m_askNextChunkAlertCmdID; }
			void SetNextChunkAlertCmdID(const char *theID);

			bool IsDevInfSent() { return m_lastServerMessageID != NULL; }
			void SetDevInfSent(bool b) { m_isDevInfSent = b; }

			bool IsInLOMode() { return m_isInLOMode; }
			void SetLOMode(bool b) { m_isInLOMode = b; }

			/// Get URL to connect to server
			const char * GetSessionURL();

			/// Set URL to be used to connect to server
			void SetSessionURL(const char *url);

			const char * GetSessionID() { return m_sessionID; }
			void SetSessionID(const char *);

			// This field is added here, because Funambol's serverID
			// is actually server's credentials username
			const char * GetServerID() { return m_serverID; }
			void SetServerID(const char *);

			void SwitchToSessionType(const char *);

			bool IsServerCredValid(Funambol::Cred *cred);

			void Reset();

		private:
			ConnectionInfo(const ConnectionInfo&);

		private:
			uint m_messageID;
			bool m_isAuthenticated;
			bool m_isDevInfSent;
			bool m_isInLOMode;	// indicates session is in lo mode -receiving or transmitting
			bool m_isWaitingAuthentication;
			bool m_isWaitingForNextChunk;	// indicates session is receiving lo and last chunk has not arrived yet
			bool m_usedAllAuthSchemes;
			char *m_askNextChunkAlertCmdID;
			char *m_sessionURL;
			char *m_nextNonce;
			char *m_nonce;
			char *m_messageIDText;
			char *m_lastServerMessageID;
			char *m_serverID;
			char *m_sessionID;
			String initialClientSessionType;
		};

		typedef boost::shared_ptr<ConnectionInfo> ConnectionInfoPtr;
		typedef std::vector<ConnectionInfoPtr> ConnInfoList;
	}
}
