/*
 * 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.
 */

#define TRACK_ARRAY_ALLOC_PROBLEM

#include <vector>
#include <sstream>
#include <algorithm>
#include "talk/xmllite/xmlelement.h"
#include "talk/base/common.h"
#include "talk/xmpp/xmppengineimpl.h"
#include "talk/xmpp/xmpplogintask.h"
#include "talk/xmpp/constants.h"
#include "talk/xmllite/xmlprinter.h"
#include "talk/xmpp/saslhandler.h"

namespace buzz {

static const std::string XMPP_CLIENT_NAMESPACES[] = {
  "stream", "http://etherx.jabber.org/streams",
  "", "jabber:client",
};

static const size_t XMPP_CLIENT_NAMESPACES_LEN = 4;

XmppEngine * XmppEngine::Create() {
  return new XmppEngineImpl();
}


XmppEngineImpl::XmppEngineImpl() :
    stanzaParseHandler_(this),
    stanzaParser_(&stanzaParseHandler_),
    engine_entered_(0),
    user_jid_(JID_EMPTY),
    password_(),
    requested_resource_(STR_EMPTY),
    tls_needed_(true),
    login_task_(new XmppLoginTask(this)),
    next_id_(0),
    bound_jid_(JID_EMPTY),
    state_(STATE_START),
    encrypted_(false),
    error_code_(ERROR_NONE),
    subcode_(0),
    stream_error_(NULL),
    raised_reset_(false),
    output_handler_(NULL),
    session_handler_(NULL),
    iq_entries_(new IqEntryVector()),
    sasl_handler_(NULL),
    output_(new std::stringstream()) {
  for (int i = 0; i < HL_COUNT; i+= 1) {
    stanza_handlers_[i].reset(new StanzaHandlerVector());
  }
}

XmppEngineImpl::~XmppEngineImpl() {
  DeleteIqCookies();
}

XmppReturnStatus
XmppEngineImpl::SetOutputHandler(XmppOutputHandler* output_handler) {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  output_handler_ = output_handler;

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::SetSessionHandler(XmppSessionHandler* session_handler) {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  session_handler_ = session_handler;

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::HandleInput(const char * bytes, size_t len) {
  if (state_ < STATE_OPENING || state_ > STATE_OPEN)
    return XMPP_RETURN_BADSTATE;

  EnterExit ee(this);

  // TODO: The return value of the xml parser is not checked.
  stanzaParser_.Parse(bytes, len, false);

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::ConnectionClosed(int subcode) {
  if (state_ != STATE_CLOSED) {
    EnterExit ee(this);
    // If told that connection closed and not already closed,
    // then connection was unpexectedly dropped.
    if (subcode) {
      SignalError(ERROR_SOCKET, subcode);
    } else {
      SignalError(ERROR_CONNECTION_CLOSED, 0);  // no subcode
    }
  }
  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::SetUseTls(bool useTls) {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  tls_needed_ = useTls;

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::SetTlsServer(const std::string & tls_server_hostname,
                             const std::string & tls_server_domain) {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  tls_server_hostname_ = tls_server_hostname;
  tls_server_domain_= tls_server_domain;

  return XMPP_RETURN_OK;
}

bool
XmppEngineImpl::GetUseTls() {
  return tls_needed_;
}

XmppReturnStatus
XmppEngineImpl::SetUser(const Jid & jid) {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  user_jid_ = jid;

  return XMPP_RETURN_OK;
}

const Jid &
XmppEngineImpl::GetUser() {
  return user_jid_;
}

XmppReturnStatus
XmppEngineImpl::SetSaslHandler(SaslHandler * sasl_handler) {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  sasl_handler_.reset(sasl_handler);
  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::SetRequestedResource(const std::string & resource) {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  requested_resource_ = resource;

  return XMPP_RETURN_OK;
}

const std::string &
XmppEngineImpl::GetRequestedResource() {
  return requested_resource_;
}

XmppReturnStatus
XmppEngineImpl::AddStanzaHandler(XmppStanzaHandler * stanza_handler,
                                 XmppEngine::HandlerLevel level) {
  if (state_ == STATE_CLOSED)
    return XMPP_RETURN_BADSTATE;

  stanza_handlers_[level]->push_back(stanza_handler);

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::RemoveStanzaHandler(XmppStanzaHandler * stanza_handler) {

  bool found = false;

  for (int level = 0; level < HL_COUNT; level += 1) {
    StanzaHandlerVector::iterator new_end =
      std::remove(stanza_handlers_[level]->begin(),
      stanza_handlers_[level]->end(),
      stanza_handler);

    if (new_end != stanza_handlers_[level]->end()) {
      stanza_handlers_[level]->erase(new_end, stanza_handlers_[level]->end());
      found = true;
    }
  }

  if (!found) {
    return XMPP_RETURN_BADARGUMENT;
  }

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::Connect() {
  if (state_ != STATE_START)
    return XMPP_RETURN_BADSTATE;

  EnterExit ee(this);

  // get the login task started
  state_ = STATE_OPENING;
  if (login_task_.get()) {
    login_task_->IncomingStanza(NULL, false);
    if (login_task_->IsDone())
      login_task_.reset();
  }

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::SendStanza(const XmlElement * element) {
  if (state_ == STATE_CLOSED)
    return XMPP_RETURN_BADSTATE;

  EnterExit ee(this);

  if (login_task_.get()) {
    // still handshaking - then outbound stanzas are queued
    login_task_->OutgoingStanza(element);
  } else {
    // handshake done - send straight through
    InternalSendStanza(element);
  }

  return XMPP_RETURN_OK;
}

XmppReturnStatus
XmppEngineImpl::SendRaw(const std::string & text) {
  if (state_ == STATE_CLOSED || login_task_.get())
    return XMPP_RETURN_BADSTATE;

  EnterExit ee(this);

  (*output_) << text;

  return XMPP_RETURN_OK;
}

std::string
XmppEngineImpl::NextId() {
  std::stringstream ss;
  ss << next_id_++;
  return ss.str();
}

XmppReturnStatus
XmppEngineImpl::Disconnect() {

  if (state_ != STATE_CLOSED) {
    EnterExit ee(this);
    if (state_ == STATE_OPEN)
      *output_ << "</stream:stream>";
    state_ = STATE_CLOSED;
  }

  return XMPP_RETURN_OK;
}

void
XmppEngineImpl::IncomingStart(const XmlElement * pelStart) {
  if (HasError() || raised_reset_)
    return;

  if (login_task_.get()) {
    // start-stream should go to login task
    login_task_->IncomingStanza(pelStart, true);
    if (login_task_->IsDone())
      login_task_.reset();
  }
  else {
    // if not logging in, it's an error to see a start
    SignalError(ERROR_XML, 0);
  }
}

void
XmppEngineImpl::IncomingStanza(const XmlElement * stanza) {
  if (HasError() || raised_reset_)
    return;

  if (stanza->Name() == QN_STREAM_ERROR) {
    // Explicit XMPP stream error
    SignalStreamError(stanza);
  } else if (login_task_.get()) {
    // Handle login handshake
    login_task_->IncomingStanza(stanza, false);
    if (login_task_->IsDone())
      login_task_.reset();
  } else if (HandleIqResponse(stanza)) {
    // iq is handled by above call
  } else {
    // give every "peek" handler a shot at all stanzas
    for (size_t i = 0; i < stanza_handlers_[HL_PEEK]->size(); i += 1) {
      (*stanza_handlers_[HL_PEEK])[i]->HandleStanza(stanza);
    }

    // give other handlers a shot in precedence order, stopping after handled
    for (int level = HL_SINGLE; level <= HL_ALL; level += 1) {
      for (size_t i = 0; i < stanza_handlers_[level]->size(); i += 1) {
        if ((*stanza_handlers_[level])[i]->HandleStanza(stanza))
          goto Handled;
      }
    }

    // If nobody wants to handle a stanza then send back an error.
    // Only do this for IQ stanzas as messages should probably just be dropped
    // and presence stanzas should certainly be dropped.
    std::string type = stanza->Attr(QN_TYPE);
    if (stanza->Name() == QN_IQ && 
        !(type == "error" || type == "result")) {
      SendStanzaError(stanza, XSE_FEATURE_NOT_IMPLEMENTED, STR_EMPTY);
    }
  }
  Handled:
    ; // handled - we're done
}

void
XmppEngineImpl::IncomingEnd(bool isError) {
  if (HasError() || raised_reset_)
    return;

  SignalError(isError ? ERROR_XML : ERROR_DOCUMENT_CLOSED, 0);
}

void
XmppEngineImpl::InternalSendStart(const std::string & to) {
  std::string hostname = tls_server_hostname_;
  if (hostname.empty()) {
    hostname = to;
  }

  // If not language is specified, the spec says use *
  std::string lang = lang_;
  if (lang.length() == 0)
    lang = "*";

  // send stream-beginning
  // note, we put a \r\n at tne end fo the first line to cause non-XMPP
  // line-oriented servers (e.g., Apache) to reveal themselves more quickly.
  *output_ << "<stream:stream to=\"" << hostname << "\" "
           << "xml:lang=\"" << lang << "\" "
           << "version=\"1.0\" "
           << "xmlns:stream=\"http://etherx.jabber.org/streams\" "
           << "xmlns=\"jabber:client\">\r\n";
}

void
XmppEngineImpl::InternalSendStanza(const XmlElement * element) {
  // It should really never be necessary to set a FROM attribute on a stanza.
  // It is implied by the bind on the stream and if you get it wrong
  // (by flipping from/to on a message?) the server will close the stream.
  ASSERT(!element->HasAttr(QN_FROM));

  // TODO: consider caching the XmlPrinter
  XmlPrinter::PrintXml(output_.get(), element,
            XMPP_CLIENT_NAMESPACES, XMPP_CLIENT_NAMESPACES_LEN);
}

std::string
XmppEngineImpl::ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) {
  return sasl_handler_->ChooseBestSaslMechanism(mechanisms, encrypted);
}

SaslMechanism *
XmppEngineImpl::GetSaslMechanism(const std::string & name) {
  return sasl_handler_->CreateSaslMechanism(name);
}

void
XmppEngineImpl::SignalBound(const Jid & fullJid) {
  if (state_ == STATE_OPENING) {
    bound_jid_ = fullJid;
    state_ = STATE_OPEN;
  }
}

void
XmppEngineImpl::SignalStreamError(const XmlElement * pelStreamError) {
  if (state_ != STATE_CLOSED) {
    stream_error_.reset(new XmlElement(*pelStreamError));
    SignalError(ERROR_STREAM, 0);
  }
}

void
XmppEngineImpl::SignalError(Error errorCode, int subCode) {
  if (state_ != STATE_CLOSED) {
    error_code_ = errorCode;
    subcode_ = subCode;
    state_ = STATE_CLOSED;
  }
}

bool
XmppEngineImpl::HasError() {
  return error_code_ != ERROR_NONE;
}

void
XmppEngineImpl::StartTls(const std::string & domain) {
  if (output_handler_) {
    output_handler_->StartTls(
      tls_server_domain_.empty() ? domain : tls_server_domain_);
    encrypted_ = true;
  }
}

XmppEngineImpl::EnterExit::EnterExit(XmppEngineImpl* engine)
  : engine_(engine),
  state_(engine->state_),
  error_(engine->error_code_) {
  engine->engine_entered_ += 1;
}

XmppEngineImpl::EnterExit::~EnterExit()  {
 XmppEngineImpl* engine = engine_;

 engine->engine_entered_ -= 1;

 bool closing = (engine->state_ != state_ &&
       engine->state_ == STATE_CLOSED);
 bool flushing = closing || (engine->engine_entered_ == 0);

 if (engine->output_handler_ && flushing) {
   std::string output = engine->output_->str();
   if (output.length() > 0)
     engine->output_handler_->WriteOutput(output.c_str(), output.length());
   engine->output_->str("");

   if (closing) {
     engine->output_handler_->CloseConnection();
     engine->output_handler_ = 0;
   }
 }

 if (engine->engine_entered_)
   return;

 if (engine->raised_reset_) {
   engine->stanzaParser_.Reset();
   engine->raised_reset_ = false;
 }

 if (engine->session_handler_) {
   if (engine->state_ != state_)
     engine->session_handler_->OnStateChange(engine->state_);
     // Note: Handling of OnStateChange(CLOSED) should allow for the
     // deletion of the engine, so no members should be accessed
     // after this line.
 }
}

}
