/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/libjingle/xmpp/xmppclient.h"

#include "webrtc/libjingle/xmpp/constants.h"
#include "webrtc/libjingle/xmpp/plainsaslhandler.h"
#include "webrtc/libjingle/xmpp/prexmppauth.h"
#include "webrtc/libjingle/xmpp/saslplainmechanism.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/stringutils.h"
#include "xmpptask.h"

namespace buzz {

class XmppClient::Private :
    public sigslot::has_slots<>,
    public XmppSessionHandler,
    public XmppOutputHandler {
public:

  explicit Private(XmppClient* client) :
    client_(client),
    socket_(),
    engine_(),
    proxy_port_(0),
    pre_engine_error_(XmppEngine::ERROR_NONE),
    pre_engine_subcode_(0),
    signal_closed_(false),
    allow_plain_(false) {}

  virtual ~Private() {
    // We need to disconnect from socket_ before engine_ is destructed (by
    // the auto-generated destructor code).
    ResetSocket();
  }

  // the owner
  XmppClient* const client_;

  // the two main objects
  std::unique_ptr<AsyncSocket> socket_;
  std::unique_ptr<XmppEngine> engine_;
  std::unique_ptr<PreXmppAuth> pre_auth_;
  rtc::CryptString pass_;
  std::string auth_mechanism_;
  std::string auth_token_;
  rtc::SocketAddress server_;
  std::string proxy_host_;
  int proxy_port_;
  XmppEngine::Error pre_engine_error_;
  int pre_engine_subcode_;
  CaptchaChallenge captcha_challenge_;
  bool signal_closed_;
  bool allow_plain_;

  void ResetSocket() {
    if (socket_) {
      socket_->SignalConnected.disconnect(this);
      socket_->SignalRead.disconnect(this);
      socket_->SignalClosed.disconnect(this);
      socket_.reset(NULL);
    }
  }

  // implementations of interfaces
  void OnStateChange(int state);
  void WriteOutput(const char* bytes, size_t len);
  void StartTls(const std::string& domainname);
  void CloseConnection();

  // slots for socket signals
  void OnSocketConnected();
  void OnSocketRead();
  void OnSocketClosed();
};

bool IsTestServer(const std::string& server_name,
                  const std::string& test_server_domain) {
  return (!test_server_domain.empty() &&
          rtc::ends_with(server_name.c_str(),
                               test_server_domain.c_str()));
}

XmppReturnStatus XmppClient::Connect(
    const XmppClientSettings& settings,
    const std::string& lang, AsyncSocket* socket, PreXmppAuth* pre_auth) {
  if (socket == NULL)
    return XMPP_RETURN_BADARGUMENT;
  if (d_->socket_)
    return XMPP_RETURN_BADSTATE;

  d_->socket_.reset(socket);

  d_->socket_->SignalConnected.connect(d_.get(), &Private::OnSocketConnected);
  d_->socket_->SignalRead.connect(d_.get(), &Private::OnSocketRead);
  d_->socket_->SignalClosed.connect(d_.get(), &Private::OnSocketClosed);

  d_->engine_.reset(XmppEngine::Create());
  d_->engine_->SetSessionHandler(d_.get());
  d_->engine_->SetOutputHandler(d_.get());
  if (!settings.resource().empty()) {
    d_->engine_->SetRequestedResource(settings.resource());
  }
  d_->engine_->SetTls(settings.use_tls());

  // The talk.google.com server returns a certificate with common-name:
  //   CN="gmail.com" for @gmail.com accounts,
  //   CN="googlemail.com" for @googlemail.com accounts,
  //   CN="talk.google.com" for other accounts (such as @example.com),
  // so we tweak the tls server setting for those other accounts to match the
  // returned certificate CN of "talk.google.com".
  // For other servers, we leave the strings empty, which causes the jid's
  // domain to be used.  We do the same for gmail.com and googlemail.com as the
  // returned CN matches the account domain in those cases.
  std::string server_name = settings.server().HostAsURIString();
  if (server_name == buzz::STR_TALK_GOOGLE_COM ||
      server_name == buzz::STR_TALKX_L_GOOGLE_COM ||
      server_name == buzz::STR_XMPP_GOOGLE_COM ||
      server_name == buzz::STR_XMPPX_L_GOOGLE_COM ||
      IsTestServer(server_name, settings.test_server_domain())) {
    if (settings.host() != STR_GMAIL_COM &&
        settings.host() != STR_GOOGLEMAIL_COM) {
      d_->engine_->SetTlsServer("", STR_TALK_GOOGLE_COM);
    }
  }

  // Set language
  d_->engine_->SetLanguage(lang);

  d_->engine_->SetUser(buzz::Jid(settings.user(), settings.host(), STR_EMPTY));

  d_->pass_ = settings.pass();
  d_->auth_mechanism_ = settings.auth_mechanism();
  d_->auth_token_ = settings.auth_token();
  d_->server_ = settings.server();
  d_->proxy_host_ = settings.proxy_host();
  d_->proxy_port_ = settings.proxy_port();
  d_->allow_plain_ = settings.allow_plain();
  d_->pre_auth_.reset(pre_auth);

  return XMPP_RETURN_OK;
}

XmppEngine::State XmppClient::GetState() const {
  if (!d_->engine_)
    return XmppEngine::STATE_NONE;
  return d_->engine_->GetState();
}

XmppEngine::Error XmppClient::GetError(int* subcode) {
  if (subcode) {
    *subcode = 0;
  }
  if (!d_->engine_)
    return XmppEngine::ERROR_NONE;
  if (d_->pre_engine_error_ != XmppEngine::ERROR_NONE) {
    if (subcode) {
      *subcode = d_->pre_engine_subcode_;
    }
    return d_->pre_engine_error_;
  }
  return d_->engine_->GetError(subcode);
}

const XmlElement* XmppClient::GetStreamError() {
  if (!d_->engine_) {
    return NULL;
  }
  return d_->engine_->GetStreamError();
}

CaptchaChallenge XmppClient::GetCaptchaChallenge() {
  if (!d_->engine_)
    return CaptchaChallenge();
  return d_->captcha_challenge_;
}

std::string XmppClient::GetAuthMechanism() {
  if (!d_->engine_)
    return "";
  return d_->auth_mechanism_;
}

std::string XmppClient::GetAuthToken() {
  if (!d_->engine_)
    return "";
  return d_->auth_token_;
}

int XmppClient::ProcessStart() {
  // Should not happen, but was observed in crash reports
  if (!d_->socket_) {
    LOG(LS_ERROR) << "socket_ already reset";
    return STATE_DONE;
  }

  if (d_->pre_auth_) {
    d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone);
    d_->pre_auth_->StartPreXmppAuth(
        d_->engine_->GetUser(), d_->server_, d_->pass_,
        d_->auth_mechanism_, d_->auth_token_);
    d_->pass_.Clear(); // done with this;
    return STATE_PRE_XMPP_LOGIN;
  }
  else {
    d_->engine_->SetSaslHandler(new PlainSaslHandler(
              d_->engine_->GetUser(), d_->pass_, d_->allow_plain_));
    d_->pass_.Clear(); // done with this;
    return STATE_START_XMPP_LOGIN;
  }
}

void XmppClient::OnAuthDone() {
  Wake();
}

int XmppClient::ProcessTokenLogin() {
  // Should not happen, but was observed in crash reports
  if (!d_->socket_) {
    LOG(LS_ERROR) << "socket_ already reset";
    return STATE_DONE;
  }

  // Don't know how this could happen, but crash reports show it as NULL
  if (!d_->pre_auth_) {
    d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
    EnsureClosed();
    return STATE_ERROR;
  }

  // Wait until pre authentication is done is done
  if (!d_->pre_auth_->IsAuthDone())
    return STATE_BLOCKED;

  if (!d_->pre_auth_->IsAuthorized()) {
    // maybe split out a case when gaia is down?
    if (d_->pre_auth_->HadError()) {
      d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
      d_->pre_engine_subcode_ = d_->pre_auth_->GetError();
    }
    else {
      d_->pre_engine_error_ = XmppEngine::ERROR_UNAUTHORIZED;
      d_->pre_engine_subcode_ = 0;
      d_->captcha_challenge_ = d_->pre_auth_->GetCaptchaChallenge();
    }
    d_->pre_auth_.reset(NULL); // done with this
    EnsureClosed();
    return STATE_ERROR;
  }

  // Save auth token as a result

  d_->auth_mechanism_ = d_->pre_auth_->GetAuthMechanism();
  d_->auth_token_ = d_->pre_auth_->GetAuthToken();

  // transfer ownership of pre_auth_ to engine
  d_->engine_->SetSaslHandler(d_->pre_auth_.release());
  return STATE_START_XMPP_LOGIN;
}

int XmppClient::ProcessStartXmppLogin() {
  // Should not happen, but was observed in crash reports
  if (!d_->socket_) {
    LOG(LS_ERROR) << "socket_ already reset";
    return STATE_DONE;
  }

  // Done with pre-connect tasks - connect!
  if (!d_->socket_->Connect(d_->server_)) {
    EnsureClosed();
    return STATE_ERROR;
  }

  return STATE_RESPONSE;
}

int XmppClient::ProcessResponse() {
  // Hang around while we are connected.
  if (!delivering_signal_ &&
      (!d_->engine_ || d_->engine_->GetState() == XmppEngine::STATE_CLOSED))
    return STATE_DONE;
  return STATE_BLOCKED;
}

XmppReturnStatus XmppClient::Disconnect() {
  if (!d_->socket_)
    return XMPP_RETURN_BADSTATE;
  Abort();
  d_->engine_->Disconnect();
  d_->ResetSocket();
  return XMPP_RETURN_OK;
}

XmppClient::XmppClient(TaskParent* parent)
    : XmppTaskParentInterface(parent),
      delivering_signal_(false),
      valid_(false) {
  d_.reset(new Private(this));
  valid_ = true;
}

XmppClient::~XmppClient() {
  valid_ = false;
}

const Jid& XmppClient::jid() const {
  return d_->engine_->FullJid();
}


std::string XmppClient::NextId() {
  return d_->engine_->NextId();
}

XmppReturnStatus XmppClient::SendStanza(const XmlElement* stanza) {
  return d_->engine_->SendStanza(stanza);
}

XmppReturnStatus XmppClient::SendStanzaError(
    const XmlElement* old_stanza, XmppStanzaError xse,
    const std::string& message) {
  return d_->engine_->SendStanzaError(old_stanza, xse, message);
}

XmppReturnStatus XmppClient::SendRaw(const std::string& text) {
  return d_->engine_->SendRaw(text);
}

XmppEngine* XmppClient::engine() {
  return d_->engine_.get();
}

void XmppClient::Private::OnSocketConnected() {
  engine_->Connect();
}

void XmppClient::Private::OnSocketRead() {
  char bytes[4096];
  size_t bytes_read;
  for (;;) {
    // Should not happen, but was observed in crash reports
    if (!socket_) {
      LOG(LS_ERROR) << "socket_ already reset";
      return;
    }

    if (!socket_->Read(bytes, sizeof(bytes), &bytes_read)) {
      // TODO: deal with error information
      return;
    }

    if (bytes_read == 0)
      return;

//#if !defined(NDEBUG)
    client_->SignalLogInput(bytes, static_cast<int>(bytes_read));
//#endif

    engine_->HandleInput(bytes, bytes_read);
  }
}

void XmppClient::Private::OnSocketClosed() {
  int code = socket_->GetError();
  engine_->ConnectionClosed(code);
}

void XmppClient::Private::OnStateChange(int state) {
  if (state == XmppEngine::STATE_CLOSED) {
    client_->EnsureClosed();
  }
  else {
    client_->SignalStateChange((XmppEngine::State)state);
  }
  client_->Wake();
}

void XmppClient::Private::WriteOutput(const char* bytes, size_t len) {
//#if !defined(NDEBUG)
  client_->SignalLogOutput(bytes, static_cast<int>(len));
//#endif

  socket_->Write(bytes, len);
  // TODO: deal with error information
}

void XmppClient::Private::StartTls(const std::string& domain) {
#if defined(FEATURE_ENABLE_SSL)
  socket_->StartTls(domain);
#endif
}

void XmppClient::Private::CloseConnection() {
  socket_->Close();
}

void XmppClient::AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) {
  d_->engine_->AddStanzaHandler(task, level);
}

void XmppClient::RemoveXmppTask(XmppTask* task) {
  d_->engine_->RemoveStanzaHandler(task);
}

void XmppClient::EnsureClosed() {
  if (!d_->signal_closed_) {
    d_->signal_closed_ = true;
    delivering_signal_ = true;
    SignalStateChange(XmppEngine::STATE_CLOSED);
    delivering_signal_ = false;
  }
}

}  // namespace buzz
