/*
 *  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_EVIL_CONSTRUCTORS(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_EVIL_CONSTRUCTORS(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_EVIL_CONSTRUCTORS(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_
