/*
 * libjingle
 * Copyright 2004--2005, 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.
 */

#include <algorithm>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include "talk/xmpp/chatroommodule.h"
#include "talk/xmpp/constants.h"
#include "talk/xmpp/moduleimpl.h"
#include "webrtc/base/common.h"

namespace buzz {

// forward declarations
class XmppChatroomImpl;
class XmppChatroomMemberImpl;

//! Module that encapsulates multiple chatrooms.
//! Each chatroom is represented by an XmppChatroomImpl instance
class XmppChatroomModuleImpl : public XmppChatroomModule,
  public XmppModuleImpl, public XmppIqHandler {
public:
  IMPLEMENT_XMPPMODULE

   // Creates a chatroom with specified Jid
  XmppChatroomModuleImpl();
  ~XmppChatroomModuleImpl();

  // XmppChatroomModule
  virtual XmppReturnStatus set_chatroom_handler(XmppChatroomHandler* handler);
  virtual XmppChatroomHandler* chatroom_handler();
  virtual XmppReturnStatus set_chatroom_jid(const Jid& chatroom_jid);
  virtual const Jid& chatroom_jid() const;
  virtual XmppReturnStatus set_nickname(const std::string& nickname);
  virtual const std::string& nickname() const;
  virtual const Jid member_jid() const;
  virtual XmppReturnStatus RequestEnterChatroom(const std::string& password,
      const std::string& client_version,
      const std::string& locale);
  virtual XmppReturnStatus RequestExitChatroom();
  virtual XmppReturnStatus RequestConnectionStatusChange(
      XmppPresenceConnectionStatus connection_status);
  virtual size_t GetChatroomMemberCount();
  virtual XmppReturnStatus CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator);
  virtual const std::string subject();
  virtual XmppChatroomState state() { return chatroom_state_; }
  virtual XmppReturnStatus SendMessage(const XmlElement& message);

  // XmppModule
  virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) {RTC_UNUSED2(cookie, pelStanza);}
  virtual bool HandleStanza(const XmlElement *);

private:
  friend class XmppChatroomMemberEnumeratorImpl;

  XmppReturnStatus ServerChangeMyPresence(const XmlElement& presence);
  XmppReturnStatus ClientChangeMyPresence(XmppChatroomState new_state);
  XmppReturnStatus ChangePresence(XmppChatroomState new_state, const XmlElement* presence, bool isServer);
  XmppReturnStatus ServerChangedOtherPresence(const XmlElement& presence_element);
  XmppChatroomEnteredStatus GetEnterFailureFromXml(const XmlElement* presence);
  XmppChatroomExitedStatus GetExitFailureFromXml(const XmlElement* presence);

  bool CheckEnterChatroomStateOk();

  void FireEnteredStatus(const XmlElement* presence,
                         XmppChatroomEnteredStatus status);
  void FireExitStatus(XmppChatroomExitedStatus status);
  void FireMessageReceived(const XmlElement& message);
  void FireMemberEntered(const XmppChatroomMember* entered_member);
  void FireMemberChanged(const XmppChatroomMember* changed_member);
  void FireMemberExited(const XmppChatroomMember* exited_member);


  typedef std::map<Jid, XmppChatroomMemberImpl*> JidMemberMap;

  XmppChatroomHandler*              chatroom_handler_;
  Jid                               chatroom_jid_;
  std::string                       nickname_;
  XmppChatroomState                 chatroom_state_;
  JidMemberMap                      chatroom_jid_members_;
  int                               chatroom_jid_members_version_;
};


class XmppChatroomMemberImpl : public XmppChatroomMember {
public:
  ~XmppChatroomMemberImpl() {}
  XmppReturnStatus SetPresence(const XmppPresence* presence);

  // XmppChatroomMember
  const Jid member_jid() const;
  const Jid full_jid() const;
  const std::string name() const;
  const XmppPresence* presence() const;

private:
  rtc::scoped_ptr<XmppPresence>  presence_;
};

class XmppChatroomMemberEnumeratorImpl :
        public XmppChatroomMemberEnumerator  {
public:
  XmppChatroomMemberEnumeratorImpl(XmppChatroomModuleImpl::JidMemberMap* chatroom_jid_members,
                                        int* map_version);

  // XmppChatroomMemberEnumerator
  virtual XmppChatroomMember* current();
  virtual bool Next();
  virtual bool Prev();
  virtual bool IsValid();
  virtual bool IsBeforeBeginning();
  virtual bool IsAfterEnd();

private:
  XmppChatroomModuleImpl::JidMemberMap*           map_;
  int                                             map_version_created_;
  int*                                            map_version_;
  XmppChatroomModuleImpl::JidMemberMap::iterator  iterator_;
  bool                                            before_beginning_;
};


// XmppChatroomModuleImpl ------------------------------------------------
XmppChatroomModule *
XmppChatroomModule::Create() {
  return new XmppChatroomModuleImpl();
}

XmppChatroomModuleImpl::XmppChatroomModuleImpl() :
  chatroom_handler_(NULL),
  chatroom_jid_(STR_EMPTY),
  chatroom_state_(XMPP_CHATROOM_STATE_NOT_IN_ROOM),
  chatroom_jid_members_version_(0) {
}

XmppChatroomModuleImpl::~XmppChatroomModuleImpl() {
  JidMemberMap::iterator iterator = chatroom_jid_members_.begin();
  while (iterator != chatroom_jid_members_.end()) {
    delete iterator->second;
    iterator++;
  }
}


bool
XmppChatroomModuleImpl::HandleStanza(const XmlElement* stanza) {
  ASSERT(engine() != NULL);

  // we handle stanzas that are for one of our chatrooms
  Jid from_jid = Jid(stanza->Attr(QN_FROM));
  // see if it's one of our chatrooms
  if (chatroom_jid_ != from_jid.BareJid()) {
    return false; // not one of our chatrooms
  } else {
    // handle presence stanza
    if (stanza->Name() == QN_PRESENCE) {
      if (from_jid == member_jid()) {
        ServerChangeMyPresence(*stanza);
      } else {
        ServerChangedOtherPresence(*stanza);
      }
    } else if (stanza->Name() == QN_MESSAGE) {
      FireMessageReceived(*stanza);
    }
    return true;
  }
}


XmppReturnStatus
XmppChatroomModuleImpl::set_chatroom_handler(XmppChatroomHandler* handler) {
  // Calling with NULL removes the handler.
  chatroom_handler_ = handler;
  return XMPP_RETURN_OK;
}


XmppChatroomHandler*
XmppChatroomModuleImpl::chatroom_handler() {
  return chatroom_handler_;
}

XmppReturnStatus
XmppChatroomModuleImpl::set_chatroom_jid(const Jid& chatroom_jid) {
  if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
    return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call,  diff error code?
  }
  if (chatroom_jid != chatroom_jid.BareJid()) {
    // chatroom_jid must be a bare jid
    return XMPP_RETURN_BADARGUMENT;
  }

  chatroom_jid_ = chatroom_jid;
  return XMPP_RETURN_OK;
}

const Jid&
XmppChatroomModuleImpl::chatroom_jid() const {
  return chatroom_jid_;
}

 XmppReturnStatus
 XmppChatroomModuleImpl::set_nickname(const std::string& nickname) {
  if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM) {
    return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call,  diff error code?
  }
  nickname_ = nickname;
  return XMPP_RETURN_OK;
 }

 const std::string&
 XmppChatroomModuleImpl::nickname() const {
  return nickname_;
 }

const Jid
XmppChatroomModuleImpl::member_jid() const {
  return Jid(chatroom_jid_.node(), chatroom_jid_.domain(), nickname_);
}


bool
XmppChatroomModuleImpl::CheckEnterChatroomStateOk() {
  if (chatroom_jid_.IsValid() == false) {
    ASSERT(0);
    return false;
  }
  if (nickname_ == STR_EMPTY) {
    ASSERT(0);
    return false;
  }
  return true;
}

std::string GetAttrValueFor(XmppPresenceConnectionStatus connection_status) {
  switch (connection_status) {
    default:
    case XMPP_CONNECTION_STATUS_UNKNOWN:
      return "";
    case XMPP_CONNECTION_STATUS_CONNECTING:
      return STR_PSTN_CONFERENCE_STATUS_CONNECTING;
    case XMPP_CONNECTION_STATUS_CONNECTED:
      return STR_PSTN_CONFERENCE_STATUS_CONNECTED;
  }
}

XmppReturnStatus
XmppChatroomModuleImpl::RequestEnterChatroom(
    const std::string& password,
    const std::string& client_version,
    const std::string& locale) {
  RTC_UNUSED(password);
  if (!engine())
    return XMPP_RETURN_BADSTATE;

  if (chatroom_state_ != XMPP_CHATROOM_STATE_NOT_IN_ROOM)
    return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call,  diff error code?

  if (CheckEnterChatroomStateOk() == false) {
    return XMPP_RETURN_BADSTATE;
  }

  // entering a chatroom is a presence request to the server
  XmlElement element(QN_PRESENCE);
  element.AddAttr(QN_TO, member_jid().Str());

  XmlElement* muc_x = new XmlElement(QN_MUC_X);
  element.AddElement(muc_x);

  if (!client_version.empty()) {
    XmlElement* client_version_element = new XmlElement(QN_CLIENT_VERSION,
                                                        false);
    client_version_element->SetBodyText(client_version);
    muc_x->AddElement(client_version_element);
  }

  if (!locale.empty()) {
    XmlElement* locale_element = new XmlElement(QN_LOCALE, false);

    locale_element->SetBodyText(locale);
    muc_x->AddElement(locale_element);
  }

  XmppReturnStatus status = engine()->SendStanza(&element);
  if (status == XMPP_RETURN_OK) {
    return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_ENTER);
  }
  return status;
}

XmppReturnStatus
XmppChatroomModuleImpl::RequestExitChatroom() {
  if (!engine())
    return XMPP_RETURN_BADSTATE;

  // exiting a chatroom is a presence request to the server
  XmlElement element(QN_PRESENCE);
  element.AddAttr(QN_TO, member_jid().Str());
  element.AddAttr(QN_TYPE, "unavailable");
  XmppReturnStatus status = engine()->SendStanza(&element);
  if (status == XMPP_RETURN_OK &&
      chatroom_state_ == XMPP_CHATROOM_STATE_IN_ROOM) {
    return ClientChangeMyPresence(XMPP_CHATROOM_STATE_REQUESTED_EXIT);
  }
  return status;
}

XmppReturnStatus
XmppChatroomModuleImpl::RequestConnectionStatusChange(
    XmppPresenceConnectionStatus connection_status) {
  if (!engine())
    return XMPP_RETURN_BADSTATE;

  if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
    // $TODO - this isn't a bad state, it's a bad call,  diff error code?
    return XMPP_RETURN_BADSTATE;
  }

  if (CheckEnterChatroomStateOk() == false) {
    return XMPP_RETURN_BADSTATE;
  }

  // entering a chatroom is a presence request to the server
  XmlElement element(QN_PRESENCE);
  element.AddAttr(QN_TO, member_jid().Str());
  element.AddElement(new XmlElement(QN_MUC_X));
  if (connection_status != XMPP_CONNECTION_STATUS_UNKNOWN) {
    XmlElement* con_status_element =
        new XmlElement(QN_GOOGLE_PSTN_CONFERENCE_STATUS);
    con_status_element->AddAttr(QN_STATUS, GetAttrValueFor(connection_status));
    element.AddElement(con_status_element);
  }
  XmppReturnStatus status = engine()->SendStanza(&element);

  return status;
}

size_t
XmppChatroomModuleImpl::GetChatroomMemberCount() {
  return chatroom_jid_members_.size();
}

XmppReturnStatus
XmppChatroomModuleImpl::CreateMemberEnumerator(XmppChatroomMemberEnumerator** enumerator) {
  *enumerator = new XmppChatroomMemberEnumeratorImpl(&chatroom_jid_members_, &chatroom_jid_members_version_);
  return XMPP_RETURN_OK;
}

const std::string
XmppChatroomModuleImpl::subject() {
  return ""; //NYI
}

XmppReturnStatus
XmppChatroomModuleImpl::SendMessage(const XmlElement& message) {
  XmppReturnStatus xmpp_status = XMPP_RETURN_OK;

  // can only send a message if we're in the room
  if (chatroom_state_ != XMPP_CHATROOM_STATE_IN_ROOM) {
    return XMPP_RETURN_BADSTATE; // $TODO - this isn't a bad state, it's a bad call,  diff error code?
  }

  if (message.Name() != QN_MESSAGE) {
    IFR(XMPP_RETURN_BADARGUMENT);
  }

  const std::string& type = message.Attr(QN_TYPE);
  if (type != "groupchat") {
    IFR(XMPP_RETURN_BADARGUMENT);
  }

  if (message.HasAttr(QN_FROM)) {
    IFR(XMPP_RETURN_BADARGUMENT);
  }

  if (message.Attr(QN_TO) != chatroom_jid_.Str()) {
    IFR(XMPP_RETURN_BADARGUMENT);
  }

  IFR(engine()->SendStanza(&message));

  return xmpp_status;
}

enum TransitionType {
  TRANSITION_TYPE_NONE                 = 0,
  TRANSITION_TYPE_ENTER_SUCCESS        = 1,
  TRANSITION_TYPE_ENTER_FAILURE        = 2,
  TRANSITION_TYPE_EXIT_VOLUNTARILY     = 3,
  TRANSITION_TYPE_EXIT_INVOLUNTARILY   = 4,
};

struct StateTransitionDescription {
  XmppChatroomState old_state;
  XmppChatroomState new_state;
  bool              is_valid_server_transition;
  bool              is_valid_client_transition;
  TransitionType    transition_type;
};

StateTransitionDescription Transitions[] = {
  { XMPP_CHATROOM_STATE_NOT_IN_ROOM,     XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, true,  TRANSITION_TYPE_NONE, },
  { XMPP_CHATROOM_STATE_NOT_IN_ROOM,     XMPP_CHATROOM_STATE_IN_ROOM,         false, false, TRANSITION_TYPE_ENTER_SUCCESS, },
  { XMPP_CHATROOM_STATE_NOT_IN_ROOM,     XMPP_CHATROOM_STATE_REQUESTED_EXIT,  false, false, TRANSITION_TYPE_NONE, },
  { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_NOT_IN_ROOM,     true,  false, TRANSITION_TYPE_ENTER_FAILURE, },
  { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_IN_ROOM,         true,  false, TRANSITION_TYPE_ENTER_SUCCESS, },
  { XMPP_CHATROOM_STATE_REQUESTED_ENTER, XMPP_CHATROOM_STATE_REQUESTED_EXIT,  false, false, TRANSITION_TYPE_NONE, },
  { XMPP_CHATROOM_STATE_IN_ROOM,         XMPP_CHATROOM_STATE_NOT_IN_ROOM,     true,  false, TRANSITION_TYPE_EXIT_INVOLUNTARILY,  },
  { XMPP_CHATROOM_STATE_IN_ROOM,         XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, false, TRANSITION_TYPE_NONE, },
  { XMPP_CHATROOM_STATE_IN_ROOM,         XMPP_CHATROOM_STATE_REQUESTED_EXIT,  false, true,  TRANSITION_TYPE_NONE, },
  { XMPP_CHATROOM_STATE_REQUESTED_EXIT,  XMPP_CHATROOM_STATE_NOT_IN_ROOM,     true,  false, TRANSITION_TYPE_EXIT_VOLUNTARILY, },
  { XMPP_CHATROOM_STATE_REQUESTED_EXIT,  XMPP_CHATROOM_STATE_REQUESTED_ENTER, false, false, TRANSITION_TYPE_NONE, },
  { XMPP_CHATROOM_STATE_REQUESTED_EXIT,  XMPP_CHATROOM_STATE_IN_ROOM,         false, false, TRANSITION_TYPE_NONE, },
};



void
XmppChatroomModuleImpl::FireEnteredStatus(const XmlElement* presence,
                                          XmppChatroomEnteredStatus status) {
  if (chatroom_handler_) {
    rtc::scoped_ptr<XmppPresence> xmpp_presence(XmppPresence::Create());
    xmpp_presence->set_raw_xml(presence);
    chatroom_handler_->ChatroomEnteredStatus(this, xmpp_presence.get(), status);
  }
}

void
XmppChatroomModuleImpl::FireExitStatus(XmppChatroomExitedStatus status) {
  if (chatroom_handler_)
    chatroom_handler_->ChatroomExitedStatus(this, status);
}

void
XmppChatroomModuleImpl::FireMessageReceived(const XmlElement& message) {
  if (chatroom_handler_)
    chatroom_handler_->MessageReceived(this, message);
}

void
XmppChatroomModuleImpl::FireMemberEntered(const XmppChatroomMember* entered_member) {
  if (chatroom_handler_)
    chatroom_handler_->MemberEntered(this, entered_member);
}

void
XmppChatroomModuleImpl::FireMemberChanged(
    const XmppChatroomMember* changed_member) {
  if (chatroom_handler_)
    chatroom_handler_->MemberChanged(this, changed_member);
}

void
XmppChatroomModuleImpl::FireMemberExited(const XmppChatroomMember* exited_member) {
  if (chatroom_handler_)
    chatroom_handler_->MemberExited(this, exited_member);
}


XmppReturnStatus
XmppChatroomModuleImpl::ServerChangedOtherPresence(const XmlElement&
                                                   presence_element) {
  XmppReturnStatus xmpp_status = XMPP_RETURN_OK;
  rtc::scoped_ptr<XmppPresence> presence(XmppPresence::Create());
  IFR(presence->set_raw_xml(&presence_element));

  JidMemberMap::iterator pos = chatroom_jid_members_.find(presence->jid());

  if (pos == chatroom_jid_members_.end()) {
    if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
      XmppChatroomMemberImpl* member = new XmppChatroomMemberImpl();
      member->SetPresence(presence.get());
      chatroom_jid_members_.insert(std::make_pair(member->member_jid(), member));
      chatroom_jid_members_version_++;
      FireMemberEntered(member);
    }
  } else {
    XmppChatroomMemberImpl* member = pos->second;
    if (presence->available() == XMPP_PRESENCE_AVAILABLE) {
      member->SetPresence(presence.get());
      chatroom_jid_members_version_++;
      FireMemberChanged(member);
    }
    else if (presence->available() == XMPP_PRESENCE_UNAVAILABLE) {
      member->SetPresence(presence.get());
      chatroom_jid_members_.erase(pos);
      chatroom_jid_members_version_++;
      FireMemberExited(member);
      delete member;
    }
  }

  return xmpp_status;
}

XmppReturnStatus
XmppChatroomModuleImpl::ClientChangeMyPresence(XmppChatroomState new_state) {
  return ChangePresence(new_state, NULL, false);
}

XmppReturnStatus
XmppChatroomModuleImpl::ServerChangeMyPresence(const XmlElement& presence) {
   XmppChatroomState new_state;

   if (presence.HasAttr(QN_TYPE) == false) {
      new_state = XMPP_CHATROOM_STATE_IN_ROOM;
   } else {
     new_state = XMPP_CHATROOM_STATE_NOT_IN_ROOM;
   }
  return ChangePresence(new_state, &presence, true);

}

XmppReturnStatus
XmppChatroomModuleImpl::ChangePresence(XmppChatroomState new_state,
                                       const XmlElement* presence,
                                       bool isServer) {
  RTC_UNUSED(presence);

  XmppChatroomState old_state = chatroom_state_;

  // do nothing if state hasn't changed
  if (old_state == new_state)
    return XMPP_RETURN_OK;

  // find the right transition description
  StateTransitionDescription* transition_desc = NULL;
  for (int i=0; i < ARRAY_SIZE(Transitions); i++) {
    if (Transitions[i].old_state == old_state &&
        Transitions[i].new_state == new_state) {
        transition_desc = &Transitions[i];
        break;
    }
  }

  if (transition_desc == NULL) {
    ASSERT(0);
    return XMPP_RETURN_BADSTATE;
  }

  // we assert for any invalid transition states, and we'll
  if (isServer) {
    // $TODO send original stanza back to server and log an error?
    // Disable the assert because of b/6133072
    // ASSERT(transition_desc->is_valid_server_transition);
    if (!transition_desc->is_valid_server_transition) {
      return XMPP_RETURN_BADSTATE;
    }
  } else {
    if (transition_desc->is_valid_client_transition == false) {
      ASSERT(0);
      return XMPP_RETURN_BADARGUMENT;
    }
  }

  // set the new state and then fire any notifications to the handler
  chatroom_state_ = new_state;

  switch (transition_desc->transition_type) {
    case TRANSITION_TYPE_ENTER_SUCCESS:
      FireEnteredStatus(presence, XMPP_CHATROOM_ENTERED_SUCCESS);
      break;
    case TRANSITION_TYPE_ENTER_FAILURE:
      FireEnteredStatus(presence, GetEnterFailureFromXml(presence));
      break;
    case TRANSITION_TYPE_EXIT_INVOLUNTARILY:
      FireExitStatus(GetExitFailureFromXml(presence));
      break;
    case TRANSITION_TYPE_EXIT_VOLUNTARILY:
      FireExitStatus(XMPP_CHATROOM_EXITED_REQUESTED);
      break;
    case TRANSITION_TYPE_NONE:
      break;
  }

  return XMPP_RETURN_OK;
}

XmppChatroomEnteredStatus
XmppChatroomModuleImpl::GetEnterFailureFromXml(const XmlElement* presence) {
  XmppChatroomEnteredStatus status = XMPP_CHATROOM_ENTERED_FAILURE_UNSPECIFIED;
  const XmlElement* error = presence->FirstNamed(QN_ERROR);
  if (error != NULL && error->HasAttr(QN_CODE)) {
    int code = atoi(error->Attr(QN_CODE).c_str());
    switch (code) {
      case 401: status = XMPP_CHATROOM_ENTERED_FAILURE_PASSWORD_REQUIRED; break;
      case 403: {
        status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BANNED;
        if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKED)) {
          status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKED;
        } else if (error->FirstNamed(QN_GOOGLE_SESSION_BLOCKING)) {
          status = XMPP_CHATROOM_ENTERED_FAILURE_MEMBER_BLOCKING;
        }
        break;
      }
      case 405: status = XMPP_CHATROOM_ENTERED_FAILURE_ROOM_LOCKED; break;
      case 406: status = XMPP_CHATROOM_ENTERED_FAILURE_OUTDATED_CLIENT; break;
      case 407: status = XMPP_CHATROOM_ENTERED_FAILURE_NOT_A_MEMBER; break;
      case 409: status = XMPP_CHATROOM_ENTERED_FAILURE_NICKNAME_CONFLICT; break;
      // http://xmpp.org/extensions/xep-0045.html#enter-maxusers
      case 503: status = XMPP_CHATROOM_ENTERED_FAILURE_MAX_USERS; break;
    }
  }
  return status;
}

XmppChatroomExitedStatus
XmppChatroomModuleImpl::GetExitFailureFromXml(const XmlElement* presence) {
  XmppChatroomExitedStatus status = XMPP_CHATROOM_EXITED_UNSPECIFIED;
  const XmlElement* muc_user = presence->FirstNamed(QN_MUC_USER_X);
  if (muc_user != NULL) {
    const XmlElement* user_status = muc_user->FirstNamed(QN_MUC_USER_STATUS);
    if (user_status != NULL && user_status->HasAttr(QN_CODE)) {
      int code = atoi(user_status->Attr(QN_CODE).c_str());
      switch (code) {
        case 307: status = XMPP_CHATROOM_EXITED_KICKED; break;
        case 322: status = XMPP_CHATROOM_EXITED_NOT_A_MEMBER; break;
        case 332: status = XMPP_CHATROOM_EXITED_SYSTEM_SHUTDOWN; break;
      }
    }
  }
  return status;
}

XmppReturnStatus
XmppChatroomMemberImpl::SetPresence(const XmppPresence* presence) {
  ASSERT(presence != NULL);

  // copy presence
  presence_.reset(XmppPresence::Create());
  presence_->set_raw_xml(presence->raw_xml());
  return XMPP_RETURN_OK;
}

const Jid
XmppChatroomMemberImpl::member_jid() const {
  return presence_->jid();
}

const Jid
XmppChatroomMemberImpl::full_jid() const {
  return Jid("");
}

const std::string
XmppChatroomMemberImpl::name() const {
  return member_jid().resource();
}

const XmppPresence*
XmppChatroomMemberImpl::presence() const {
  return presence_.get();
}


// XmppChatroomMemberEnumeratorImpl --------------------------------------
XmppChatroomMemberEnumeratorImpl::XmppChatroomMemberEnumeratorImpl(
        XmppChatroomModuleImpl::JidMemberMap* map, int* map_version) {
  map_ = map;
  map_version_ = map_version;
  map_version_created_ = *map_version_;
  iterator_ = map->begin();
  before_beginning_ = true;
}

XmppChatroomMember*
XmppChatroomMemberEnumeratorImpl::current() {
  if (IsValid() == false) {
    return NULL;
  } else if (IsBeforeBeginning() || IsAfterEnd()) {
    return NULL;
  } else {
    return iterator_->second;
  }
}

bool
XmppChatroomMemberEnumeratorImpl::Prev() {
  if (IsValid() == false) {
    return false;
  } else if (IsBeforeBeginning()) {
    return false;
  } else if (iterator_ == map_->begin()) {
    before_beginning_ = true;
    return false;
  } else {
    iterator_--;
    return current() != NULL;
  }
}

bool
XmppChatroomMemberEnumeratorImpl::Next() {
  if (IsValid() == false) {
    return false;
  } else if (IsBeforeBeginning()) {
    before_beginning_ = false;
    iterator_ = map_->begin();
    return current() != NULL;
  } else if (IsAfterEnd()) {
    return false;
  } else {
    iterator_++;
    return current() != NULL;
  }
}

bool
XmppChatroomMemberEnumeratorImpl::IsValid() {
  return map_version_created_ == *map_version_;
}

bool
XmppChatroomMemberEnumeratorImpl::IsBeforeBeginning() {
  return before_beginning_;
}

bool
XmppChatroomMemberEnumeratorImpl::IsAfterEnd() {
  return (iterator_ == map_->end());
}



} // namespace buzz
