/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _xmppengineimpl_h_
#define _xmppengineimpl_h_

#include <sstream>
#include <vector>
#include "talk/xmpp/xmppengine.h"
#include "talk/xmpp/xmppstanzaparser.h"

namespace buzz {

class XmppLoginTask;
class XmppEngine;
class XmppIqEntry;
class SaslHandler;
class SaslMechanism;

//! The XMPP connection engine.
//! This engine implements the client side of the 'core' XMPP protocol.
//! To use it, register an XmppOutputHandler to handle socket output
//! and pass socket input to HandleInput.  Then application code can
//! set up the connection with a user, password, and other settings,
//! and then call Connect() to initiate the connection.
//! An application can listen for events and receive stanzas by
//! registering an XmppStanzaHandler via AddStanzaHandler().
class XmppEngineImpl : public XmppEngine {
public:
  XmppEngineImpl();
  virtual ~XmppEngineImpl();

  // SOCKET INPUT AND OUTPUT ------------------------------------------------

  //! Registers the handler for socket output
  virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh);

  //! Provides socket input to the engine
  virtual XmppReturnStatus HandleInput(const char * bytes, size_t len);

  //! Advises the engine that the socket has closed
  virtual XmppReturnStatus ConnectionClosed(int subcode);

  // SESSION SETUP ---------------------------------------------------------

  //! Indicates the (bare) JID for the user to use.
  virtual XmppReturnStatus SetUser(const Jid & jid);

  //! Get the login (bare) JID.
  virtual const Jid & GetUser();

  //! Indicates the autentication to use.  Takes ownership of the object.
  virtual XmppReturnStatus SetSaslHandler(SaslHandler * sasl_handler);

  //! Sets whether TLS will be used within the connection (default true).
  virtual XmppReturnStatus SetTls(TlsOptions useTls);

  //! Sets an alternate domain from which we allows TLS certificates.
  //! This is for use in the case where a we want to allow a proxy to
  //! serve up its own certificate rather than one owned by the underlying
  //! domain.
  virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname,
                                        const std::string & proxy_domain);

  //! Gets whether TLS will be used within the connection.
  virtual TlsOptions GetTls();

  //! Sets the request resource name, if any (optional).
  //! Note that the resource name may be overridden by the server; after
  //! binding, the actual resource name is available as part of FullJid().
  virtual XmppReturnStatus SetRequestedResource(const std::string& resource);

  //! Gets the request resource name.
  virtual const std::string & GetRequestedResource();

  //! Sets language
  virtual void SetLanguage(const std::string & lang) {
    lang_ = lang;
  }

  // SESSION MANAGEMENT ---------------------------------------------------

  //! Set callback for state changes.
  virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler);

  //! Initiates the XMPP connection.
  //! After supplying connection settings, call this once to initiate,
  //! (optionally) encrypt, authenticate, and bind the connection.
  virtual XmppReturnStatus Connect();

  //! The current engine state.
  virtual State GetState() { return state_; }

  //! Returns true if the connection is encrypted (under TLS)
  virtual bool IsEncrypted() { return encrypted_; }

  //! The error code.
  //! Consult this after XmppOutputHandler.OnClose().
  virtual Error GetError(int *subcode) {
     if (subcode) {
       *subcode = subcode_;
     }
     return error_code_;
  }

  //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
  //! Notice the stanza returned is owned by the XmppEngine and
  //! is deleted when the engine is destroyed.
  virtual const XmlElement * GetStreamError() { return stream_error_.get(); }

  //! Closes down the connection.
  //! Sends CloseConnection to output, and disconnects and registered
  //! session handlers.  After Disconnect completes, it is guaranteed
  //! that no further callbacks will be made.
  virtual XmppReturnStatus Disconnect();

  // APPLICATION USE -------------------------------------------------------

  //! Adds a listener for session events.
  //! Stanza delivery is chained to session handlers; the first to
  //! return 'true' is the last to get each stanza.
  virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler,
                                            XmppEngine::HandlerLevel level);

  //! Removes a listener for session events.
  virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler);

  //! Sends a stanza to the server.
  virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza);

  //! Sends raw text to the server
  virtual XmppReturnStatus SendRaw(const std::string & text);

  //! Sends an iq to the server, and registers a callback for the result.
  //! Returns the cookie passed to the result handler.
  virtual XmppReturnStatus SendIq(const XmlElement* pelStanza,
                                  XmppIqHandler* iq_handler,
                                  XmppIqCookie* cookie);

  //! Unregisters an iq callback handler given its cookie.
  //! No callback will come to this handler after it's unregistered.
  virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
                                      XmppIqHandler** iq_handler);

  //! Forms and sends an error in response to the given stanza.
  //! Swaps to and from, sets type to "error", and adds error information
  //! based on the passed code.  Text is optional and may be STR_EMPTY.
  virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
                                           XmppStanzaError code,
                                           const std::string & text);

  //! The fullly bound JID.
  //! This JID is only valid after binding has succeeded.  If the value
  //! is JID_NULL, the binding has not succeeded.
  virtual const Jid & FullJid() { return bound_jid_; }

  //! The next unused iq id for this connection.
  //! Call this when building iq stanzas, to ensure that each iq
  //! gets its own unique id.
  virtual std::string NextId();

private:
  friend class XmppLoginTask;
  friend class XmppIqEntry;

  void IncomingStanza(const XmlElement *pelStanza);
  void IncomingStart(const XmlElement *pelStanza);
  void IncomingEnd(bool isError);

  void InternalSendStart(const std::string & domainName);
  void InternalSendStanza(const XmlElement * pelStanza);
  std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted);
  SaslMechanism * GetSaslMechanism(const std::string & name);
  void SignalBound(const Jid & fullJid);
  void SignalStreamError(const XmlElement * pelStreamError);
  void SignalError(Error errorCode, int subCode);
  bool HasError();
  void DeleteIqCookies();
  bool HandleIqResponse(const XmlElement * element);
  void StartTls(const std::string & domain);
  void RaiseReset() { raised_reset_ = true; }

  class StanzaParseHandler : public XmppStanzaParseHandler {
  public:
    StanzaParseHandler(XmppEngineImpl * outer) : outer_(outer) {}
    virtual ~StanzaParseHandler() {}
    virtual void StartStream(const XmlElement * pelStream)
      { outer_->IncomingStart(pelStream); }
    virtual void Stanza(const XmlElement * pelStanza)
      { outer_->IncomingStanza(pelStanza); }
    virtual void EndStream()
      { outer_->IncomingEnd(false); }
    virtual void XmlError()
      { outer_->IncomingEnd(true); }
  private:
    XmppEngineImpl * const outer_;
  };

  class EnterExit {
   public:
    EnterExit(XmppEngineImpl* engine);
    ~EnterExit();
   private:
    XmppEngineImpl* engine_;
    State state_;
    Error error_;

  };

  friend class StanzaParseHandler;
  friend class EnterExit;

  StanzaParseHandler stanzaParseHandler_;
  XmppStanzaParser stanzaParser_;


  // state
  int engine_entered_;
  Jid user_jid_;
  std::string password_;
  std::string requested_resource_;
  TlsOptions tls_option_;
  std::string tls_server_hostname_;
  std::string tls_server_domain_;
  talk_base::scoped_ptr<XmppLoginTask> login_task_;
  std::string lang_;

  int next_id_;
  Jid bound_jid_;
  State state_;
  bool encrypted_;
  Error error_code_;
  int subcode_;
  talk_base::scoped_ptr<XmlElement> stream_error_;
  bool raised_reset_;
  XmppOutputHandler* output_handler_;
  XmppSessionHandler* session_handler_;

  typedef std::vector<XmppStanzaHandler*> StanzaHandlerVector;
  talk_base::scoped_ptr<StanzaHandlerVector> stanza_handlers_[HL_COUNT];

  typedef std::vector<XmppIqEntry*> IqEntryVector;
  talk_base::scoped_ptr<IqEntryVector> iq_entries_;

  talk_base::scoped_ptr<SaslHandler> sasl_handler_;

  talk_base::scoped_ptr<std::stringstream> output_;
};

}


#endif
