/*
 *  Copyright 2013 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.
 */

#include "p2p/base/transport_description.h"

#include <cstddef>
#include <optional>
#include <string>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "api/rtc_error.h"
#include "p2p/base/p2p_constants.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/ssl_fingerprint.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {
namespace {

// ice-char = ALPHA / DIGIT / "+" / "/", RFC 8839 section 5.6.
bool IsValidIceChar(char c) {
  return absl::ascii_isalnum(c) || c == '+' || c == '/';
}

bool IsIceChar(char c) {
  // Note: '-', '=', '#' and '_' are *not* valid ice-chars but temporarily
  // permitted in order to allow external software to upgrade.
  if (c == '-' || c == '=' || c == '#' || c == '_') {
    RTC_LOG(LS_WARNING)
        << "'-', '=', '#' and '_' are not valid ice-char and thus not "
        << "permitted in ufrag or pwd. This is a protocol violation that "
        << "is permitted to allow upgrading but will be rejected in "
        << "the future. See https://crbug.com/1053756";
    return true;
  }
  return IsValidIceChar(c);
}

RTCError ValidateIceUfrag(absl::string_view raw_ufrag) {
  if (!(ICE_UFRAG_MIN_LENGTH <= raw_ufrag.size() &&
        raw_ufrag.size() <= ICE_UFRAG_MAX_LENGTH)) {
    StringBuilder sb;
    sb << "ICE ufrag must be between " << ICE_UFRAG_MIN_LENGTH << " and "
       << ICE_UFRAG_MAX_LENGTH << " characters long.";
    return RTCError(RTCErrorType::SYNTAX_ERROR, sb.Release());
  }

  if (!absl::c_all_of(raw_ufrag, IsIceChar)) {
    return RTCError(
        RTCErrorType::SYNTAX_ERROR,
        "ICE ufrag must contain only alphanumeric characters, '+', and '/'.");
  }

  return RTCError::OK();
}

RTCError ValidateIcePwd(absl::string_view raw_pwd) {
  if (!(ICE_PWD_MIN_LENGTH <= raw_pwd.size() &&
        raw_pwd.size() <= ICE_PWD_MAX_LENGTH)) {
    StringBuilder sb;
    sb << "ICE pwd must be between " << ICE_PWD_MIN_LENGTH << " and "
       << ICE_PWD_MAX_LENGTH << " characters long.";
    return RTCError(RTCErrorType::SYNTAX_ERROR, sb.Release());
  }

  if (!absl::c_all_of(raw_pwd, IsIceChar)) {
    return RTCError(
        RTCErrorType::SYNTAX_ERROR,
        "ICE pwd must contain only alphanumeric characters, '+', and '/'.");
  }

  return RTCError::OK();
}

}  // namespace

RTCErrorOr<IceParameters> IceParameters::Parse(absl::string_view raw_ufrag,
                                               absl::string_view raw_pwd) {
  IceParameters parameters(std::string(raw_ufrag), std::string(raw_pwd),
                           /* ice_renomination= */ false);
  auto result = parameters.Validate();
  if (!result.ok()) {
    return result;
  }
  return parameters;
}

RTCError IceParameters::Validate() const {
  // For legacy protocols.
  // TODO(zhihuang): Remove this once the legacy protocol is no longer
  // supported.
  if (ufrag.empty() && pwd.empty()) {
    return RTCError::OK();
  }

  auto ufrag_result = ValidateIceUfrag(ufrag);
  if (!ufrag_result.ok()) {
    return ufrag_result;
  }

  auto pwd_result = ValidateIcePwd(pwd);
  if (!pwd_result.ok()) {
    return pwd_result;
  }

  return RTCError::OK();
}

std::optional<ConnectionRole> StringToConnectionRole(
    absl::string_view role_str) {
  const char* const roles[] = {
      CONNECTIONROLE_ACTIVE_STR, CONNECTIONROLE_PASSIVE_STR,
      CONNECTIONROLE_ACTPASS_STR, CONNECTIONROLE_HOLDCONN_STR};

  for (size_t i = 0; i < std::size(roles); ++i) {
    if (absl::EqualsIgnoreCase(roles[i], role_str)) {
      return static_cast<ConnectionRole>(CONNECTIONROLE_ACTIVE + i);
    }
  }
  return std::nullopt;
}

bool ConnectionRoleToString(const ConnectionRole& role, std::string* role_str) {
  switch (role) {
    case CONNECTIONROLE_ACTIVE:
      *role_str = CONNECTIONROLE_ACTIVE_STR;
      break;
    case CONNECTIONROLE_ACTPASS:
      *role_str = CONNECTIONROLE_ACTPASS_STR;
      break;
    case CONNECTIONROLE_PASSIVE:
      *role_str = CONNECTIONROLE_PASSIVE_STR;
      break;
    case CONNECTIONROLE_HOLDCONN:
      *role_str = CONNECTIONROLE_HOLDCONN_STR;
      break;
    default:
      return false;
  }
  return true;
}

TransportDescription::TransportDescription()
    : ice_mode(ICEMODE_FULL),
      connection_role(CONNECTIONROLE_NONE),
      cryptex(false) {}

TransportDescription::TransportDescription(
    const std::vector<std::string>& transport_options,
    absl::string_view ice_ufrag,
    absl::string_view ice_pwd,
    IceMode ice_mode,
    ConnectionRole role,
    const SSLFingerprint* identity_fingerprint)
    : transport_options(transport_options),
      ice_ufrag(ice_ufrag),
      ice_pwd(ice_pwd),
      ice_mode(ice_mode),
      connection_role(role),
      identity_fingerprint(CopyFingerprint(identity_fingerprint)),
      cryptex(false) {}

TransportDescription::TransportDescription(absl::string_view ice_ufrag,
                                           absl::string_view ice_pwd)
    : ice_ufrag(ice_ufrag),
      ice_pwd(ice_pwd),
      ice_mode(ICEMODE_FULL),
      connection_role(CONNECTIONROLE_NONE),
      cryptex(false) {}

TransportDescription::TransportDescription(const TransportDescription& from)
    : transport_options(from.transport_options),
      ice_ufrag(from.ice_ufrag),
      ice_pwd(from.ice_pwd),
      ice_mode(from.ice_mode),
      connection_role(from.connection_role),
      identity_fingerprint(CopyFingerprint(from.identity_fingerprint.get())),
      cryptex(from.cryptex) {}

TransportDescription::~TransportDescription() = default;

TransportDescription& TransportDescription::operator=(
    const TransportDescription& from) {
  // Self-assignment
  if (this == &from)
    return *this;

  transport_options = from.transport_options;
  ice_ufrag = from.ice_ufrag;
  ice_pwd = from.ice_pwd;
  ice_mode = from.ice_mode;
  connection_role = from.connection_role;

  identity_fingerprint.reset(CopyFingerprint(from.identity_fingerprint.get()));
  cryptex = from.cryptex;
  return *this;
}

void TransportDescription::AddOption(absl::string_view option) {
  // ice-option-tag is 1*ice-char, RFC 8839 section 5.6.
  RTC_DCHECK(!option.empty() && absl::c_all_of(option, IsValidIceChar))
      << "Invalid ice-option-tag: " << option;
  transport_options.emplace_back(option);
}

}  // namespace webrtc
