// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "buffet/notification/xmpp_iq_stanza_handler.h"

#include <base/bind.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>

#include "buffet/notification/xml_node.h"
#include "buffet/notification/xmpp_channel.h"

namespace buffet {

namespace {

// Default timeout for <iq> requests to the server. If the response hasn't been
// received within this time interval, the request is considered as failed.
const int kTimeoutIntervalSeconds = 30;

// Builds an XML stanza that looks like this:
//  <iq id='${id}' type='${type}' from='${from}' to='${to}'>$body</iq>
// where 'to' and 'from' are optional attributes.
std::string BuildIqStanza(const std::string& id,
                          const std::string& type,
                          const std::string& to,
                          const std::string& from,
                          const std::string& body) {
  std::string to_attr;
  if (!to.empty()) {
    CHECK_EQ(std::string::npos, to.find_first_of("<'>"))
        << "Destination address contains invalid XML characters";
    base::StringAppendF(&to_attr, " to='%s'", to.c_str());
  }
  std::string from_attr;
  if (!from.empty()) {
    CHECK_EQ(std::string::npos, from.find_first_of("<'>"))
        << "Source address contains invalid XML characters";
    base::StringAppendF(&from_attr, " from='%s'", from.c_str());
  }
  return base::StringPrintf("<iq id='%s' type='%s'%s%s>%s</iq>",
                            id.c_str(), type.c_str(), from_attr.c_str(),
                            to_attr.c_str(), body.c_str());
}

}  // anonymous namespace

IqStanzaHandler::IqStanzaHandler(
    XmppChannelInterface* xmpp_channel,
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
    : xmpp_channel_{xmpp_channel}, task_runner_{task_runner} {}

void IqStanzaHandler::SendRequest(
    const std::string& type,
    const std::string& from,
    const std::string& to,
    const std::string& body,
    const ResponseCallback& response_callback,
    const TimeoutCallback& timeout_callback) {
  return SendRequestWithCustomTimeout(
      type, from, to, body,
      base::TimeDelta::FromSeconds(kTimeoutIntervalSeconds), response_callback,
      timeout_callback);
}

void IqStanzaHandler::SendRequestWithCustomTimeout(
    const std::string& type,
    const std::string& from,
    const std::string& to,
    const std::string& body,
    base::TimeDelta timeout,
    const ResponseCallback& response_callback,
    const TimeoutCallback& timeout_callback) {
  // Remember the response callback to call later.
  requests_.emplace(++last_request_id_, response_callback);
  // Schedule a time-out callback for this request.
  if (timeout < base::TimeDelta::Max()) {
    task_runner_->PostDelayedTask(
        FROM_HERE,
        base::Bind(&IqStanzaHandler::OnTimeOut, weak_ptr_factory_.GetWeakPtr(),
                   last_request_id_, timeout_callback),
        timeout);
  }

  std::string message = BuildIqStanza(std::to_string(last_request_id_),
                                      type, to, from, body);
  xmpp_channel_->SendMessage(message);
}

bool IqStanzaHandler::HandleIqStanza(std::unique_ptr<XmlNode> stanza) {
  std::string type;
  if (!stanza->GetAttribute("type", &type)) {
    LOG(ERROR) << "IQ stanza missing 'type' attribute";
    return false;
  }

  std::string id_str;
  if (!stanza->GetAttribute("id", &id_str)) {
    LOG(ERROR) << "IQ stanza missing 'id' attribute";
    return false;
  }

  if (type == "result" || type == "error") {
    // These are response stanzas from the server.
    // Find the corresponding request.
    RequestId id;
    if (!base::StringToInt(id_str, &id)) {
      LOG(ERROR) << "IQ stanza's 'id' attribute is invalid";
      return false;
    }
    auto p = requests_.find(id);
    if (p != requests_.end()) {
      task_runner_->PostTask(
          FROM_HERE,
          base::Bind(p->second, base::Passed(std::move(stanza))));
      requests_.erase(p);
    }
  } else {
    // We do not support server-initiated IQ requests ("set" / "get" / "query").
    // So just reply with "not implemented" error (and swap "to"/"from" attrs).
    std::string error_body =
        "<error type='modify'>"
        "<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
        "</error>";
    std::string message = BuildIqStanza(id_str, "error",
                                        stanza->GetAttributeOrEmpty("from"),
                                        stanza->GetAttributeOrEmpty("to"),
                                        error_body);
    xmpp_channel_->SendMessage(message);
  }
  return true;
}

void IqStanzaHandler::OnTimeOut(RequestId id,
                                const TimeoutCallback& timeout_callback) {
  // Request has not been processed yes, so a real timeout occurred.
  if (requests_.erase(id) > 0)
    timeout_callback.Run();
}

}  // namespace buffet
