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

  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;

  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_;

  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; }

#ifdef _DEBUG
  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_;

#ifdef _DEBUG
  bool debug_force_timeout_;
#endif
};

}  // namespace buzz

#endif // WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_
