/*
 * libjingle
 * Copyright 2011, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_XMPP_PUBSUBSTATECLIENT_H_
#define TALK_XMPP_PUBSUBSTATECLIENT_H_

#include <map>
#include <string>
#include <vector>

#include "webrtc/libjingle/xmllite/qname.h"
#include "webrtc/libjingle/xmllite/xmlelement.h"
#include "talk/xmpp/constants.h"
#include "talk/xmpp/jid.h"
#include "talk/xmpp/pubsubclient.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/sigslotrepeater.h"

namespace buzz {

// To handle retracts correctly, we need to remember certain details
// about an item.  We could just cache the entire XML element, but
// that would take more memory and require re-parsing.
struct StateItemInfo {
  std::string published_nick;
  std::string publisher_nick;
};

// Represents a PubSub state change.  Usually, the key is the nick,
// but not always.  It's a per-state-type thing.  Look below on how keys are
// computed.
template <typename C>
struct PubSubStateChange {
  // The nick of the user changing the state.
  std::string publisher_nick;
  // The nick of the user whose state is changing.
  std::string published_nick;
  C old_state;
  C new_state;
};

// Knows how to handle specific states and XML.
template <typename C>
class PubSubStateSerializer {
 public:
  virtual ~PubSubStateSerializer() {}
  virtual XmlElement* Write(const QName& state_name, const C& state) = 0;
  virtual void Parse(const XmlElement* state_elem, C* state_out) = 0;
};

// Knows how to create "keys" for states, which determines their
// uniqueness.  Most states are per-nick, but block is
// per-blocker-and-blockee.  This is independent of itemid, especially
// in the case of presenter state.
class PubSubStateKeySerializer {
 public:
  virtual ~PubSubStateKeySerializer() {}
  virtual std::string GetKey(const std::string& publisher_nick,
                             const std::string& published_nick) = 0;
};

class PublishedNickKeySerializer : public PubSubStateKeySerializer {
 public:
  virtual std::string GetKey(const std::string& publisher_nick,
                             const std::string& published_nick);
};

class PublisherAndPublishedNicksKeySerializer
  : public PubSubStateKeySerializer {
 public:
  virtual std::string GetKey(const std::string& publisher_nick,
                             const std::string& published_nick);
};

// Adapts PubSubClient to be specifically suited for pub sub call
// states.  Signals state changes and keeps track of keys, which are
// normally nicks.
template <typename C>
class PubSubStateClient : public sigslot::has_slots<> {
 public:
  // Gets ownership of the serializers, but not the client.
  PubSubStateClient(const std::string& publisher_nick,
                    PubSubClient* client,
                    const QName& state_name,
                    C default_state,
                    PubSubStateKeySerializer* key_serializer,
                    PubSubStateSerializer<C>* state_serializer)
      : publisher_nick_(publisher_nick),
        client_(client),
        state_name_(state_name),
        default_state_(default_state) {
    key_serializer_.reset(key_serializer);
    state_serializer_.reset(state_serializer);
    client_->SignalItems.connect(
        this, &PubSubStateClient<C>::OnItems);
    client_->SignalPublishResult.connect(
        this, &PubSubStateClient<C>::OnPublishResult);
    client_->SignalPublishError.connect(
        this, &PubSubStateClient<C>::OnPublishError);
    client_->SignalRetractResult.connect(
        this, &PubSubStateClient<C>::OnRetractResult);
    client_->SignalRetractError.connect(
        this, &PubSubStateClient<C>::OnRetractError);
  }

  virtual ~PubSubStateClient() {}

  virtual void Publish(const std::string& published_nick,
                       const C& state,
                       std::string* task_id_out) {
    std::string key = key_serializer_->GetKey(publisher_nick_, published_nick);
    std::string itemid = state_name_.LocalPart() + ":" + key;
    if (StatesEqual(state, default_state_)) {
      client_->RetractItem(itemid, task_id_out);
    } else {
      XmlElement* state_elem = state_serializer_->Write(state_name_, state);
      state_elem->AddAttr(QN_NICK, published_nick);
      client_->PublishItem(itemid, state_elem, task_id_out);
    }
  }

  sigslot::signal1<const PubSubStateChange<C>&> SignalStateChange;
  // Signal (task_id, item).  item is NULL for retract.
  sigslot::signal2<const std::string&,
  const XmlElement*> SignalPublishResult;
  // Signal (task_id, item, error stanza).  item is NULL for retract.
  sigslot::signal3<const std::string&,
  const XmlElement*,
  const XmlElement*> SignalPublishError;

 protected:
  // return false if retracted item (no info or state given)
  virtual bool ParseStateItem(const PubSubItem& item,
                              StateItemInfo* info_out,
                              C* state_out) {
    const XmlElement* state_elem = item.elem->FirstNamed(state_name_);
    if (state_elem == NULL) {
      return false;
    }

    info_out->publisher_nick =
        client_->GetPublisherNickFromPubSubItem(item.elem);
    info_out->published_nick = state_elem->Attr(QN_NICK);
    state_serializer_->Parse(state_elem, state_out);
    return true;
  }

  virtual bool StatesEqual(const C& state1, const C& state2) {
    return state1 == state2;
  }

  PubSubClient* client() { return client_; }
  const QName& state_name() { return state_name_; }

 private:
  void OnItems(PubSubClient* pub_sub_client,
               const std::vector<PubSubItem>& items) {
    for (std::vector<PubSubItem>::const_iterator item = items.begin();
         item != items.end(); ++item) {
      OnItem(*item);
    }
  }

  void OnItem(const PubSubItem& item) {
    const std::string& itemid = item.itemid;
    StateItemInfo info;
    C new_state;

    bool retracted = !ParseStateItem(item, &info, &new_state);
    if (retracted) {
      bool known_itemid =
          (info_by_itemid_.find(itemid) != info_by_itemid_.end());
      if (!known_itemid) {
        // Nothing to retract, and nothing to publish.
        // Probably a different state type.
        return;
      } else {
        info = info_by_itemid_[itemid];
        info_by_itemid_.erase(itemid);
        new_state = default_state_;
      }
    } else {
      // TODO: Assert new key matches the known key. It
      // shouldn't change!
      info_by_itemid_[itemid] = info;
    }

    std::string key = key_serializer_->GetKey(
        info.publisher_nick, info.published_nick);
    bool has_old_state = (state_by_key_.find(key) != state_by_key_.end());
    C old_state = has_old_state ? state_by_key_[key] : default_state_;
    if ((retracted && !has_old_state) || StatesEqual(new_state, old_state)) {
      // Nothing change, so don't bother signalling.
      return;
    }

    if (retracted || StatesEqual(new_state, default_state_)) {
      // We treat a default state similar to a retract.
      state_by_key_.erase(key);
    } else {
      state_by_key_[key] = new_state;
    }

    PubSubStateChange<C> change;
    if (!retracted) {
      // Retracts do not have publisher information.
      change.publisher_nick = info.publisher_nick;
    }
    change.published_nick = info.published_nick;
    change.old_state = old_state;
    change.new_state = new_state;
    SignalStateChange(change);
  }

  void OnPublishResult(PubSubClient* pub_sub_client,
                       const std::string& task_id,
                       const XmlElement* item) {
    SignalPublishResult(task_id, item);
  }

  void OnPublishError(PubSubClient* pub_sub_client,
                      const std::string& task_id,
                      const buzz::XmlElement* item,
                      const buzz::XmlElement* stanza) {
    SignalPublishError(task_id, item, stanza);
  }

  void OnRetractResult(PubSubClient* pub_sub_client,
                       const std::string& task_id) {
    // There's no point in differentiating between publish and retract
    // errors, so we simplify by making them both signal a publish
    // result.
    const XmlElement* item = NULL;
    SignalPublishResult(task_id, item);
  }

  void OnRetractError(PubSubClient* pub_sub_client,
                      const std::string& task_id,
                      const buzz::XmlElement* stanza) {
    // There's no point in differentiating between publish and retract
    // errors, so we simplify by making them both signal a publish
    // error.
    const XmlElement* item = NULL;
    SignalPublishError(task_id, item, stanza);
  }

  std::string publisher_nick_;
  PubSubClient* client_;
  const QName state_name_;
  C default_state_;
  rtc::scoped_ptr<PubSubStateKeySerializer> key_serializer_;
  rtc::scoped_ptr<PubSubStateSerializer<C> > state_serializer_;
  // key => state
  std::map<std::string, C> state_by_key_;
  // itemid => StateItemInfo
  std::map<std::string, StateItemInfo> info_by_itemid_;

  DISALLOW_COPY_AND_ASSIGN(PubSubStateClient);
};
}  // namespace buzz

#endif  // TALK_XMPP_PUBSUBSTATECLIENT_H_
