// Copyright 2017 The Chromium 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 "remoting/signaling/signaling_address.h"

#include <string.h>

#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "remoting/base/name_value_map.h"
#include "remoting/base/remoting_bot.h"
#include "remoting/base/service_urls.h"
#include "remoting/signaling/jid_util.h"
#include "third_party/libjingle_xmpp/xmllite/xmlelement.h"

namespace remoting {

namespace {

constexpr char kJingleNamespace[] = "urn:xmpp:jingle:1";
constexpr char kLcsResourcePrefix[] = "chromoting_lcs_";

// FTL JID format:
// user@domain.com/chromoting_ftl_(registration ID)
// The FTL JID is only used local to the program.
constexpr char kFtlResourcePrefix[] = "chromoting_ftl_";

// Represents the XML attrbute names for the various address fields in the
// iq stanza.
enum class Field { JID, CHANNEL, ENDPOINT_ID };

const NameMapElement<SignalingAddress::Channel> kChannelTypes[] = {
    {SignalingAddress::Channel::LCS, "lcs"},
    {SignalingAddress::Channel::XMPP, "xmpp"},
    {SignalingAddress::Channel::FTL, "ftl"},
};

jingle_xmpp::QName GetQNameByField(Field attr, SignalingAddress::Direction direction) {
  const char* attribute_name = nullptr;
  switch (attr) {
    case Field::JID:
      attribute_name = (direction == SignalingAddress::FROM) ? "from" : "to";
      break;
    case Field::ENDPOINT_ID:
      attribute_name = (direction == SignalingAddress::FROM)
                           ? "from-endpoint-id"
                           : "to-endpoint-id";
      break;
    case Field::CHANNEL:
      attribute_name =
          (direction == SignalingAddress::FROM) ? "from-channel" : "to-channel";
      break;
  }
  return jingle_xmpp::QName("", attribute_name);
}

SignalingAddress::Channel GetChannelType(std::string address) {
  std::string bare_jid;
  std::string resource;
  bool has_jid_resource = SplitJidResource(address, &bare_jid, &resource);
  if (has_jid_resource) {
    if (resource.find(kLcsResourcePrefix) == 0) {
      return SignalingAddress::Channel::LCS;
    }
    if (resource.find(kFtlResourcePrefix) == 0) {
      return SignalingAddress::Channel::FTL;
    }
  }
  return SignalingAddress::Channel::XMPP;
}

}  // namespace

SignalingAddress::SignalingAddress()
    : channel_(SignalingAddress::Channel::XMPP) {}

SignalingAddress::SignalingAddress(const std::string& address) {
  channel_ = GetChannelType(address);
  switch (channel_) {
    case SignalingAddress::Channel::XMPP:
      jid_ = NormalizeJid(address);
      break;
    case SignalingAddress::Channel::LCS:
      endpoint_id_ = NormalizeJid(address);
      jid_ = remoting::ServiceUrls::GetInstance()->directory_bot_jid();
      break;
    case SignalingAddress::Channel::FTL:
      jid_ = NormalizeJid(address);
      break;
    default:
      NOTREACHED();
  }

  DCHECK(!jid_.empty()) << "Missing JID.";
  DCHECK(endpoint_id_.empty() != (channel_ == Channel::LCS))
      << "EndpointId should be set if and only if the Channel is LCS";
}

SignalingAddress::SignalingAddress(const std::string& jid,
                                   const std::string& endpoint_id,
                                   Channel channel)
    : jid_(NormalizeJid(jid)),
      endpoint_id_(NormalizeJid(endpoint_id)),
      channel_(channel) {
  DCHECK(!jid.empty());
}

bool SignalingAddress::operator==(const SignalingAddress& other) const {
  return (other.jid_ == jid_) && (other.endpoint_id_ == endpoint_id_) &&
         (other.channel_ == channel_);
}

bool SignalingAddress::operator!=(const SignalingAddress& other) const {
  return !(*this == other);
}

// static
SignalingAddress SignalingAddress::CreateFtlSignalingAddress(
    const std::string& username,
    const std::string& registration_id) {
  return SignalingAddress(base::StringPrintf("%s/%s%s", username.c_str(),
                                             kFtlResourcePrefix,
                                             registration_id.c_str()));
}

// static
SignalingAddress SignalingAddress::Parse(const jingle_xmpp::XmlElement* iq,
                                         SignalingAddress::Direction direction,
                                         std::string* error) {
  std::string jid(iq->Attr(GetQNameByField(Field::JID, direction)));
  if (jid.empty()) {
    return SignalingAddress();
  }

  const jingle_xmpp::XmlElement* jingle =
      iq->FirstNamed(jingle_xmpp::QName(kJingleNamespace, "jingle"));

  if (!jingle || GetChannelType(jid) == SignalingAddress::Channel::FTL) {
    return SignalingAddress(jid);
  }

  std::string type(iq->Attr(jingle_xmpp::QName(std::string(), "type")));
  // For error IQs, invert the direction as the jingle node represents the
  // original request.
  if (type == "error") {
    direction = (direction == FROM) ? TO : FROM;
  }

  std::string endpoint_id(
      jingle->Attr(GetQNameByField(Field::ENDPOINT_ID, direction)));
  std::string channel_str(
      jingle->Attr(GetQNameByField(Field::CHANNEL, direction)));
  SignalingAddress::Channel channel;

  if (channel_str.empty()) {
    channel = SignalingAddress::Channel::XMPP;
  } else if (!NameToValue(kChannelTypes, channel_str, &channel)) {
    *error = "Unknown channel: " + channel_str;
    return SignalingAddress();
  }

  bool is_lcs = (channel == SignalingAddress::Channel::LCS);

  if (is_lcs == endpoint_id.empty()) {
    *error = (is_lcs ? "Missing |endpoint-id| for LCS channel"
                     : "|endpoint_id| should be empty for XMPP channel");
    return SignalingAddress();
  }

  if (direction == FROM && is_lcs && !IsValidBotJid(jid)) {
    *error = "Reject LCS message from untrusted sender: " + jid;
    return SignalingAddress();
  }

  return SignalingAddress(jid, endpoint_id, channel);
}

void SignalingAddress::SetInMessage(jingle_xmpp::XmlElement* iq,
                                    Direction direction) const {
  DCHECK(!empty()) << "Signaling Address is empty";

  if (direction == FROM) {
    // The from JID is not used for routing but for sender identification on the
    // receiving end. Use the ID for specificity.
    iq->SetAttr(GetQNameByField(Field::JID, direction), id());
  } else {
    // The to JID is used for routing and must be a valid XMPP endpoint.  Always
    // use the XMPP JID.
    iq->SetAttr(GetQNameByField(Field::JID, direction), jid_);
  }

  // Do not tamper the routing-info in the jingle tag for error IQ's, as
  // it corresponds to the original message.
  std::string type(iq->Attr(jingle_xmpp::QName(std::string(), "type")));
  if (type == "error") {
    return;
  }

  jingle_xmpp::XmlElement* jingle =
      iq->FirstNamed(jingle_xmpp::QName(kJingleNamespace, "jingle"));

  if (jingle) {
    // Start from a fresh slate regardless of the previous address format.
    jingle->ClearAttr(GetQNameByField(Field::CHANNEL, direction));
    jingle->ClearAttr(GetQNameByField(Field::ENDPOINT_ID, direction));

    // Only set the channel and endpoint_id in the LCS channel.
    if (channel_ == SignalingAddress::Channel::LCS) {
      jingle->AddAttr(GetQNameByField(Field::ENDPOINT_ID, direction),
                      endpoint_id_);
      jingle->AddAttr(GetQNameByField(Field::CHANNEL, direction),
                      ValueToName(kChannelTypes, channel_));
    }
  }
}

bool SignalingAddress::GetFtlInfo(std::string* username,
                                  std::string* registration_id) const {
  if (channel_ != Channel::FTL) {
    return false;
  }
  std::string resource;
  bool has_jid_resource = SplitJidResource(jid_, username, &resource);
  DCHECK(has_jid_resource);
  size_t ftl_resource_prefix_length = strlen(kFtlResourcePrefix);
  DCHECK_LT(ftl_resource_prefix_length, resource.length());
  *registration_id = resource.substr(ftl_resource_prefix_length);
  return true;
}

}  // namespace remoting
