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

#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_
#define WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_

#include <deque>
#include <string>
#include "webrtc/libjingle/xmpp/xmppengine.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/task.h"
#include "webrtc/base/taskparent.h"

namespace buzz {

/////////////////////////////////////////////////////////////////////
//
// XMPPTASK
//
/////////////////////////////////////////////////////////////////////
//
// See Task and XmppClient first.
//
// XmppTask is a task that is designed to go underneath XmppClient and be
// useful there.  It has a way of finding its XmppClient parent so you
// can have it nested arbitrarily deep under an XmppClient and it can
// still find the XMPP services.
//
// Tasks register themselves to listen to particular kinds of stanzas
// that are sent out by the client.  Rather than processing stanzas
// right away, they should decide if they own the sent stanza,
// and if so, queue it and Wake() the task, or if a stanza does not belong
// to you, return false right away so the next XmppTask can take a crack.
// This technique (synchronous recognize, but asynchronous processing)
// allows you to have arbitrary logic for recognizing stanzas yet still,
// for example, disconnect a client while processing a stanza -
// without reentrancy problems.
//
/////////////////////////////////////////////////////////////////////

class XmppTask;

// XmppClientInterface is an abstract interface for sending and
// handling stanzas.  It can be implemented for unit tests or
// different network environments.  It will usually be implemented by
// XmppClient.
class XmppClientInterface {
 public:
  XmppClientInterface();
  virtual ~XmppClientInterface();

  virtual XmppEngine::State GetState() const = 0;
  virtual const Jid& jid() const = 0;
  virtual std::string NextId() = 0;
  virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0;
  virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza,
                                           XmppStanzaError error_code,
                                           const std::string& message) = 0;
  virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0;
  virtual void RemoveXmppTask(XmppTask* task) = 0;
  sigslot::signal0<> SignalDisconnected;

  RTC_DISALLOW_COPY_AND_ASSIGN(XmppClientInterface);
};

// XmppTaskParentInterface is the interface require for any parent of
// an XmppTask.  It needs, for example, a way to get an
// XmppClientInterface.

// We really ought to inherit from a TaskParentInterface, but we tried
// that and it's way too complicated to change
// Task/TaskParent/TaskRunner.  For now, this works.
class XmppTaskParentInterface : public rtc::Task {
 public:
  explicit XmppTaskParentInterface(rtc::TaskParent* parent)
      : Task(parent) {
  }
  virtual ~XmppTaskParentInterface() {}

  virtual XmppClientInterface* GetClient() = 0;

  RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskParentInterface);
};

class XmppTaskBase : public XmppTaskParentInterface {
 public:
  explicit XmppTaskBase(XmppTaskParentInterface* parent)
      : XmppTaskParentInterface(parent),
        parent_(parent) {
  }
  virtual ~XmppTaskBase() {}

  virtual XmppClientInterface* GetClient() {
    return parent_->GetClient();
  }

 protected:
  XmppTaskParentInterface* parent_;

  RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskBase);
};

class XmppTask : public XmppTaskBase,
                 public XmppStanzaHandler,
                 public sigslot::has_slots<>
{
 public:
  XmppTask(XmppTaskParentInterface* parent,
           XmppEngine::HandlerLevel level = XmppEngine::HL_NONE);
  virtual ~XmppTask();

  std::string task_id() const { return id_; }
  void set_task_id(std::string id) { id_ = id; }

#if !defined(NDEBUG)
  void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; }
#endif

  virtual bool HandleStanza(const XmlElement* stanza) { return false; }

 protected:
  XmppReturnStatus SendStanza(const XmlElement* stanza);
  XmppReturnStatus SetResult(const std::string& code);
  XmppReturnStatus SendStanzaError(const XmlElement* element_original,
                                   XmppStanzaError code,
                                   const std::string& text);

  virtual void Stop();
  virtual void OnDisconnect();

  virtual void QueueStanza(const XmlElement* stanza);
  const XmlElement* NextStanza();

  bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid);

  bool MatchResponseIq(const XmlElement* stanza, const Jid& to,
                       const std::string& task_id);

  static bool MatchRequestIq(const XmlElement* stanza, const std::string& type,
                             const QName& qn);
  static XmlElement *MakeIqResult(const XmlElement* query);
  static XmlElement *MakeIq(const std::string& type,
                            const Jid& to, const std::string& task_id);

  // Returns true if the task is under the specified rate limit and updates the
  // rate limit accordingly
  bool VerifyTaskRateLimit(const std::string task_name, int max_count,
                           int per_x_seconds);

private:
  void StopImpl();

  bool stopped_;
  std::deque<XmlElement*> stanza_queue_;
  rtc::scoped_ptr<XmlElement> next_stanza_;
  std::string id_;

#if !defined(NDEBUG)
  bool debug_force_timeout_;
#endif
};

}  // namespace buzz

#endif // WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_
