/*
 * 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 TALK_XMPP_XMPPENGINEIMPL_H_
#define TALK_XMPP_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* stanza);

  //! 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* stanza,
                                  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 *stanza);
  void IncomingStart(const XmlElement *stanza);
  void IncomingEnd(bool isError);

  void InternalSendStart(const std::string& domainName);
  void InternalSendStanza(const XmlElement* stanza);
  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* streamError);
  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* stream) {
      outer_->IncomingStart(stream);
    }
    virtual void Stanza(const XmlElement* stanza) {
      outer_->IncomingStanza(stanza);
    }
    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 stanza_parse_handler_;
  XmppStanzaParser stanza_parser_;

  // 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_;

  XmlnsStack xmlns_stack_;

  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_;
};

}  // namespace buzz

#endif  // TALK_XMPP_XMPPENGINEIMPL_H_
