/***************************************************************************
                          msnsocketbase.h  -  description
                             -------------------
    begin                : Thu Apr 1 2008
    copyright            : (C) 2008 by Valerio Pilo
    email                : valerio@kmess.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef MSNSOCKETBASE_H
#define MSNSOCKETBASE_H

#include <QStringList>

// Forward declarations
class CurrentAccount;
class QAuthenticator;
class QNetworkProxy;



/**
 * @brief Base class and interface for the MSN Socket classes.
 * 
 * The class defines the interface expected by MsnConnection for all socket implementations.
 * Currently there is a socket implementation for normal TCP-based connections (MsnSocketTcp)
 * and a socket for MSN-over-HTTP (MsnSocketHttp).
 *
 * @author Mike K. Bennett
 * @author Valerio Pilo <valerio@kmess.org>
 * @ingroup NetworkCore
 */
class MsnSocketBase : public QObject
{
  Q_OBJECT

  public: // Public enumerations
    /// Type of server that will be connected from this socket
    enum ServerType
    {
      SERVER_NOTIFICATION     /// The connection is to a notification server
    , SERVER_SWITCHBOARD      /// The connection is to a switchboard server
    };
    /// Types of errors with connection sockets
    enum ErrorType
    {
    /// These are generic socket and connection errors
      ERROR_UNKNOWN = 0            /// An unspecified error has occurred
    , ERROR_CONNECTING             /// There was an error while establishing the connection
    , ERROR_PROXY                  /// The configured proxy could not found/is invalid/etc.
    , ERROR_CONNECTING_GATEWAY     /// There was an error while establishing the HTTP connection
    , ERROR_DROP                   /// The connection was dropped
    , ERROR_DATA                   /// An error within the data was received
    , ERROR_CONNECTION_TIME_LIMIT  /// The connection was not successful within the time limit
    , ERROR_CONNECTION_OTHER       /// The current account has connected from elsewhere, disconnecting us
    , ERROR_AUTH_TIME_LIMIT        /// The authentication/login was not successful within the time limit
    , ERROR_AUTH_LOGIN             /// The authentication/login failed due to wrong username or password
    , ERROR_AUTH_COMPUTATION       /// The hash could not be computed
    /// The next are server-reported errors
    , ERROR_USER                   /// An error caused by the user
    , ERROR_SERVER                 /// Server error
    , ERROR_INTERNAL               /// Internal KMess error (we did something the server didn't like)
    , ERROR_SOAP_UNKNOWN           /// SOAP error: unknown error - failed reimplementation of parseSoapFault()?
    , ERROR_SOAP_RESPONSE          /// SOAP error: the webservice response was not valid
    , ERROR_SOAP_TIME_LIMIT        /// SOAP error: the webservice request was not successful within the time limit
    , ERROR_SOAP_AUTHENTICATION    /// SOAP error: the webservice had required an authentication (usually shouldn't)
    , ERROR_SOAP_TOOMANYREDIRECTS  /// SOAP error: the webservice is redirecting us too many times
    };


  public: // Public methods
    // The constructor
                       MsnSocketBase( ServerType serverType );
    // The destructor
                      ~MsnSocketBase();
    // Connect to the given server via the socket
    virtual void       connectToServer( const QString& server = QString(), const quint16 port = 0 ) = 0;
    // Disconnect from the server, if connected
    virtual void       disconnectFromServer( bool isTransfer = false ) = 0;
    // Get the IP address of this machine.
    virtual QString    getLocalIp() const = 0;
    // Return which payload commands are accepted by this connection
    QStringList        getAcceptedPayloadCommands();
    // Return the type of server connection managed by the socket
    virtual ServerType getServerType() const;
    // Whether or not the connection is active
    virtual bool       isConnected() const;
    // Test whether the given command is an error.
    bool               isErrorCommand( const QString &command ) const;
    // Test whether the given command is a payload command
    virtual bool       isPayloadCommand( const QString &command ) const;
    // Specify which accepted commands carry payload data for this connection
    virtual void       setAcceptedPayloadCommands( QStringList commandList );
    // Set whether we're sending pings or not
    virtual void       setSendPings( bool sendPings ) = 0;
    // Write data to the socket without conversions
    virtual qint64     writeBinaryData( const QByteArray& data ) = 0;
    // Write data to the socket
    virtual qint64     writeData( const QString& data ) = 0;


  protected:  // Protected properties
    // List of accepted commands which carry a data payload
    QStringList        acceptedPayloadCommands_;
    // State variable to detect if the connection is active
    bool               connected_;
    // The type of server which we will connect to (notification,switchboard,...)
    ServerType         serverType_;

  protected slots:
    // Ask the user to authenticate on a proxy
    virtual void       proxyAuthenticate( const QNetworkProxy &proxy, QAuthenticator *authenticator );

  signals: // Public signals
    // Signal that the server has connected
    void               connected();
    // Signal that incoming data is ready to be parsed
    void               dataReceived( const QStringList &commandLine, const QByteArray &payloadData );
    // Signal that the server has disconnected
    void               disconnected();
    // Signal that an error has occurred
    void               error( QString error, MsnSocketBase::ErrorType type );
    // Signal that a ping to the connection has been sent
    void               pingSent();
    // Signal to send information to the main window's status bar
    void               statusMessage( QString message, bool isError );

};

#endif
