/*
 *  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/constants.h"
#include "webrtc/libjingle/xmpp/xmppclient.h"
#include "webrtc/libjingle/xmpp/xmppengine.h"
#include "webrtc/libjingle/xmpp/xmpptask.h"

namespace buzz {

XmppClientInterface::XmppClientInterface() {
}

XmppClientInterface::~XmppClientInterface() {
}

XmppTask::XmppTask(XmppTaskParentInterface* parent,
                   XmppEngine::HandlerLevel level)
    : XmppTaskBase(parent), stopped_(false) {
#ifdef _DEBUG
  debug_force_timeout_ = false;
#endif

  id_ = GetClient()->NextId();
  GetClient()->AddXmppTask(this, level);
  GetClient()->SignalDisconnected.connect(this, &XmppTask::OnDisconnect);
}

XmppTask::~XmppTask() {
  StopImpl();
}

void XmppTask::StopImpl() {
  while (NextStanza() != NULL) {}
  if (!stopped_) {
    GetClient()->RemoveXmppTask(this);
    GetClient()->SignalDisconnected.disconnect(this);
    stopped_ = true;
  }
}

XmppReturnStatus XmppTask::SendStanza(const XmlElement* stanza) {
  if (stopped_)
    return XMPP_RETURN_BADSTATE;
  return GetClient()->SendStanza(stanza);
}

XmppReturnStatus XmppTask::SendStanzaError(const XmlElement* element_original,
                                           XmppStanzaError code,
                                           const std::string& text) {
  if (stopped_)
    return XMPP_RETURN_BADSTATE;
  return GetClient()->SendStanzaError(element_original, code, text);
}

void XmppTask::Stop() {
  StopImpl();
  Task::Stop();
}

void XmppTask::OnDisconnect() {
  Error();
}

void XmppTask::QueueStanza(const XmlElement* stanza) {
#ifdef _DEBUG
  if (debug_force_timeout_)
    return;
#endif

  stanza_queue_.push_back(new XmlElement(*stanza));
  Wake();
}

const XmlElement* XmppTask::NextStanza() {
  XmlElement* result = NULL;
  if (!stanza_queue_.empty()) {
    result = stanza_queue_.front();
    stanza_queue_.pop_front();
  }
  next_stanza_.reset(result);
  return result;
}

XmlElement* XmppTask::MakeIq(const std::string& type,
                             const buzz::Jid& to,
                             const std::string& id) {
  XmlElement* result = new XmlElement(QN_IQ);
  if (!type.empty())
    result->AddAttr(QN_TYPE, type);
  if (!to.IsEmpty())
    result->AddAttr(QN_TO, to.Str());
  if (!id.empty())
    result->AddAttr(QN_ID, id);
  return result;
}

XmlElement* XmppTask::MakeIqResult(const XmlElement * query) {
  XmlElement* result = new XmlElement(QN_IQ);
  result->AddAttr(QN_TYPE, STR_RESULT);
  if (query->HasAttr(QN_FROM)) {
    result->AddAttr(QN_TO, query->Attr(QN_FROM));
  }
  result->AddAttr(QN_ID, query->Attr(QN_ID));
  return result;
}

bool XmppTask::MatchResponseIq(const XmlElement* stanza,
                               const Jid& to,
                               const std::string& id) {
  if (stanza->Name() != QN_IQ)
    return false;

  if (stanza->Attr(QN_ID) != id)
    return false;

  return MatchStanzaFrom(stanza, to);
}

bool XmppTask::MatchStanzaFrom(const XmlElement* stanza,
                               const Jid& to) {
  Jid from(stanza->Attr(QN_FROM));
  if (from == to)
    return true;

  // We address the server as "", check if we are doing so here.
  if (!to.IsEmpty())
    return false;

  // It is legal for the server to identify itself with "domain" or
  // "myself@domain"
  Jid me = GetClient()->jid();
  return (from == Jid(me.domain())) || (from == me.BareJid());
}

bool XmppTask::MatchRequestIq(const XmlElement* stanza,
                              const std::string& type,
                              const QName& qn) {
  if (stanza->Name() != QN_IQ)
    return false;

  if (stanza->Attr(QN_TYPE) != type)
    return false;

  if (stanza->FirstNamed(qn) == NULL)
    return false;

  return true;
}

}
