/*
 * 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 SetUseTls(bool 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 bool GetUseTls();

  //! 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_;
  bool tls_needed_;
  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
