/*
==============================================================================
  Name		: WebClientEngine.h

 Description: 

 Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
 All rights reserved.
 This component and the accompanying materials are made available
 under the terms of the License "Eclipse Public License v1.0"
 which accompanies this distribution, and is available
 at the URL "http://www.eclipse.org/legal/epl-v10.html".

 Contributors:
 Nokia Corporation - initial contribution.

 Based on the CWebClientEngine class in the S60 SDK WebClient 
 example application.
 ==============================================================================
*/

#ifndef WEBCLIENTENGINE_H
#define WEBCLIENTENGINE_H

// INCLUDES
#include <coecntrl.h>
#include <http.h>
#include <http/mhttpauthenticationcallback.h>
#include <es_sock.h>

// CONSTANTS
const TInt KMaxHeaderNameLength	 = 32;
const TInt KMaxHeaderValueLength	= 128;
const TInt KMaxAuthTypeLength	   = 128;
const TInt KMaxDateTimeStringLength = 40;
const TInt KMaxStatusTextLength	 = 32;
const TInt KMaxUserNameLength	   = 128;
const TInt KMaxPasswordLength	   = 128;

// Used user agent for requests
_LIT8( KUserAgent, "WebClient 1.0" );

// This client accepts all content types.
// (change to e.g. "text/plain" for plain text only)
_LIT8( KAccept, "*/*" );

// Format for output of data/time values
_LIT( KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3" );

// Some texts for header output
_LIT( KColon, ": " );
_LIT( Krealm, "Realm: " );

class CWebClientEngine;

// CLASS DECLARATION

/**
* MWebClientObserver
* CWebClientEngine passes events and responses body data with this interface. 
* An instance of this class must be provided for construction of CWebClientEngine.
*/
class MWebClientObserver 
	{
	public:
		/**
		 * ClientOpenSessionFailedL( CWebClientEngine& anEngine )
		 * An error occurred opening the HTTP session. The calling code
		 * will leave after this method returns.
		 * @param anError: the error code
		 * Most common error; no access point configured, and session creation
		 * leaves with KErrNotFound.
		 */
		virtual void ClientOpenSessionFailedL( CWebClientEngine& anEngine, TInt anError ) = 0;
		/**
		 * ClientConnectingL()
		 * Called to notify that a connection was initiated
		 */
		virtual void ClientConnectingL( CWebClientEngine& anEngine ) = 0;
 
		/**
		* ClientHeaderReceivedL()
		* Called when HTTP header is received.
		* @param aHeaderData: Header field name and value
		*/
		virtual void ClientHeaderReceivedL( CWebClientEngine& anEngine, const TDesC& aHeaderData ) = 0;

		/**
		* ClientBodyReceivedL()
		* Called when a part of the HTTP body is received.
		* @param aBodyData:  Part of the body data received. (e.g. part of
		*					the received HTML page)
		*/
		virtual void ClientBodyReceivedL( CWebClientEngine& anEngine, const TDesC8& aBodyData ) = 0;

		/**
		 * ClientConnectionCanceledL()
		 * Called to notify that a connection attempt has been canceled
		 */
		virtual void ClientConnectionCanceledL( CWebClientEngine& anEngine ) = 0;
		
		/**
		 * ClientResponseCompleteL
		 * Called to notify that a transaction's response is complete.
		 * See TTransactionEvent::EResponseComplete
		 */
		virtual void ClientResponseCompleteL( CWebClientEngine& anEngine ) = 0;
		
		/**
		 * ClientTransactionSucceeded()
		 * Called to notify that a transaction completed successfully
		 * See TTransactionEvent::ESucceeded
		 */
		virtual void ClientTransactionSucceededL( CWebClientEngine& anEngine ) = 0;
		
		/** 
		 * ClientTransactionFailed()
		 * Catch-all for failure. 
		 * See TTransactionEvent::EFailed
		 */
		 virtual void ClientTransactionFailedL( CWebClientEngine& anEngine ) = 0;
		 
		/**
		 * ClientUnknownEventL()
		 * Called to notify that an unknown HTTP event has
		 * been received.
		 * @param aStatus: the iStatus field of the event
		 * See THTTPEvent::iStatus
		 */
		 virtual void ClientUnknownEventL( CWebClientEngine& anEngine , TInt aStatus ) = 0;
		
		/**
		 * ClientRunErrorL()
		 * Called when a error occurs in the handling of a transaction event.
		 * @param anError: the error code
		 */
		virtual void ClientRunErrorL( CWebClientEngine& anEngine , TInt anError) = 0;
		
		/**
		 * ClientGetCredentialsL()
		 * Called when authentication has been requested by the server.
		 * Return EFalse for no authentication or e.g. the user cancels
		 * an input dialog. Otherwise return the user name and password 
		 * as out parameters along with an ETrue result.
		 * @param aUri: the current URI
		 * @param aRealm: the realm associated with the request
		 * @param aUserName: the returned user name
		 * @param aPassword: the returned password
		 */
		virtual TBool ClientGetCredentialsL( CWebClientEngine& anEngine, const TUriC8& aUri, 
								const TDesC8& aRealm, 
								TDes& aUsername, 
								TDes& aPassword ) = 0;
		
	};

/**
* CWebClientEngine
* Provides simple interface to HTTP Client API.
*/
class CWebClientEngine : public CBase, 
						 public MHTTPTransactionCallback,
						 public MHTTPAuthenticationCallback
	{
	public:
		/**
		* NewL()
		* Create a CWebClientEngine object.
		* @param  iObserver: 
		* @return A pointer to the created instance of CWebClientEngine
		*/
		static CWebClientEngine* NewL( MWebClientObserver& aObserver );

		/**
		* NewLC()
		* Create a CWebClientEngine object.
		* @param  iObserver:
		* @return A pointer to the created instance of CWebClientEngine
		*/
		static CWebClientEngine* NewLC( MWebClientObserver& aObserver );

		/**
		* ~CWebClientEngine()
		* Destroy the object
		*/
		~CWebClientEngine();
		
		/**
		 * Opens the HTTP session. Automatically called when a session is initiated,
		 * or can be called separately.
		 */
		void OpenSessionL();

		/**
		* IssueHTTPGetL()
		* Starts a new HTTP GET transaction.
		* @param aUri: URI to get. (e.g. http://host.org")
		*/
		void IssueHTTPGetL( const TDesC8& aUri );

		/**
		* CancelTransactionL()
		* Closes currently running transaction and frees resources related to it.
		*/
		void CancelTransactionL();

		/**
		* IsRunning()
		* Checks if the transaction is running.
		* @return ETrue, if transaction is currently running.
		*/
		inline TBool IsRunning() { return iRunning; };

	private:
		/**
		* ConstructL()
		* Perform the second phase construction of a CWebClientEngine object.
		*/
		void ConstructL();

		/**
		* CWebClientEngine()
		* Perform the first phase of two phase construction.
		* @param iObserver: 
		*/
		CWebClientEngine( MWebClientObserver& iObserver );

		/**
		* SetHeaderL()
		* Sets header value of an HTTP request.
		* @param aHeaders:  Headers of the HTTP request
		* @param aHdrField: Enumerated HTTP header field, e.g. HTTP::EUserAgent
		* @param aHdrValue: New value for header field
		*/
		void SetHeaderL( RHTTPHeaders aHeaders, TInt aHdrField, 
						 const TDesC8& aHdrValue );

		/**
		* DumpRespHeadersL()
		* Called when HTTP header is received.
		* Displays HTTP header field names and values
		* @param aTransaction: The transaction that is processed.
		*/
		void DumpRespHeadersL( RHTTPTransaction& aTransantion );

		/**
		* HandleRunErrorL()
		* Called from MHFRunError() when *leave* occurs in handling of transaction event. 
		* @param aError:	   The leave code that occured.
		*/
		void HandleRunErrorL( TInt aError );

	/**
	* From MHTTPSessionEventCallback
	*/
	private:
		/**
		* MHFRunL()
		* Called by framework to notify about transaction events.
		* @param aTransaction: Transaction, where the event occured.
		* @param aEvent:	   Occured event.
		*/
		void MHFRunL( RHTTPTransaction aTransaction, const THTTPEvent& aEvent );

		/**
		* MHFRunError()
		* Called by framework when *leave* occurs in handling of transaction event. 
		* @param aError:	   The leave code that occured.
		* @param aTransaction: The transaction that was being processed when leave occured.
		* @param aEvent:	   The event that was being processed when leave occured.
		* @return KErrNone,	if the error was handled. Otherwise the value of aError, or
		*					  some other error value. Returning error value causes causes 
		*					  HTTP-CORE 6 panic.
		*/
		TInt MHFRunError( TInt aError, 
							RHTTPTransaction aTransaction, 
							const THTTPEvent& aEvent );

	/**
	* From MHTTPAuthenticationCallback (needed for HTTP authentication)
	*/
	private:
		/**
		* GetCredentialsL()
		* Called by framework when username and password for requested URI is 
		* needed.
		* @param aURI: The URI being requested (e.g. "http://host.org")
		* @param aRealm: The realm being requested (e.g. "user@host.org")
		* @param aAuthenticationType: Authentication type. (e.g. "Basic")
		* @param aUsername: Given user name.
		* @param aPassword: Given password.
		* @return A pointer to the created document
		*/
		TBool GetCredentialsL(  const TUriC8& aUri, 
								RString aRealm, 
								RStringF aAuthenticationType, 
								RString& aUsername, 
								RString& aPassword );
								
	private: // Data
		RHTTPSession			iSession;
		RHTTPTransaction		iTransaction;
		RSocketServ 			iSocketServ;
		RConnection 			iConnection;
		
		MWebClientObserver&	 iObserver;	  // Used for passing body data and
												// events to UI.
		TBool					iSessionOpened; // ETrue, if session successfully opened
		TBool				   iRunning;	   // ETrue, if transaction running
	};

#endif // WEBCLIENTENGINE_H
