/*
 *  Copyright (c) 2017 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 "call/rtp_config.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <optional>
#include <string>
#include <vector>

#include "absl/algorithm/container.h"
#include "api/array_view.h"
#include "api/rtp_headers.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {

namespace {

uint32_t FindAssociatedSsrc(uint32_t ssrc,
                            const std::vector<uint32_t>& ssrcs,
                            const std::vector<uint32_t>& associated_ssrcs) {
  RTC_DCHECK_EQ(ssrcs.size(), associated_ssrcs.size());
  for (size_t i = 0; i < ssrcs.size(); ++i) {
    if (ssrcs[i] == ssrc)
      return associated_ssrcs[i];
  }
  RTC_DCHECK_NOTREACHED();
  return 0;
}

}  // namespace

std::string LntfConfig::ToString() const {
  return enabled ? "{enabled: true}" : "{enabled: false}";
}

std::string NackConfig::ToString() const {
  char buf[1024];
  rtc::SimpleStringBuilder ss(buf);
  ss << "{rtp_history_ms: " << rtp_history_ms;
  ss << '}';
  return ss.str();
}

std::string UlpfecConfig::ToString() const {
  char buf[1024];
  rtc::SimpleStringBuilder ss(buf);
  ss << "{ulpfec_payload_type: " << ulpfec_payload_type;
  ss << ", red_payload_type: " << red_payload_type;
  ss << ", red_rtx_payload_type: " << red_rtx_payload_type;
  ss << '}';
  return ss.str();
}

bool UlpfecConfig::operator==(const UlpfecConfig& other) const {
  return ulpfec_payload_type == other.ulpfec_payload_type &&
         red_payload_type == other.red_payload_type &&
         red_rtx_payload_type == other.red_rtx_payload_type;
}

std::string RtpStreamConfig::ToString() const {
  char buf[1024];
  rtc::SimpleStringBuilder ss(buf);
  ss << "{ssrc: " << ssrc;
  ss << ", rid: " << rid;
  ss << ", payload_name: " << payload_name;
  ss << ", payload_type: " << payload_type;
  ss << ", raw_payload: " << (raw_payload ? "true" : "false");
  if (rtx.has_value()) {
    ss << ", rtx: " << rtx->ToString();
  }
  ss << '}';
  return ss.str();
}

std::string RtpStreamConfig::Rtx::ToString() const {
  char buf[1024];
  rtc::SimpleStringBuilder ss(buf);
  ss << "{ssrc: " << ssrc;
  ss << ", payload_type: " << payload_type;
  ss << '}';
  return ss.str();
}

RtpConfig::RtpConfig() = default;
RtpConfig::RtpConfig(const RtpConfig&) = default;
RtpConfig::~RtpConfig() = default;

RtpConfig::Flexfec::Flexfec() = default;
RtpConfig::Flexfec::Flexfec(const Flexfec&) = default;
RtpConfig::Flexfec::~Flexfec() = default;

std::string RtpConfig::ToString() const {
  char buf[2 * 1024];
  rtc::SimpleStringBuilder ss(buf);
  ss << "{ssrcs: [";
  for (size_t i = 0; i < ssrcs.size(); ++i) {
    ss << ssrcs[i];
    if (i != ssrcs.size() - 1)
      ss << ", ";
  }
  ss << "], rids: [";
  for (size_t i = 0; i < rids.size(); ++i) {
    ss << rids[i];
    if (i != rids.size() - 1)
      ss << ", ";
  }
  ss << "], mid: '" << mid << "'";
  ss << ", rtcp_mode: "
     << (rtcp_mode == RtcpMode::kCompound ? "RtcpMode::kCompound"
                                          : "RtcpMode::kReducedSize");
  ss << ", max_packet_size: " << max_packet_size;
  ss << ", extmap-allow-mixed: " << (extmap_allow_mixed ? "true" : "false");
  ss << ", extensions: [";
  for (size_t i = 0; i < extensions.size(); ++i) {
    ss << extensions[i].ToString();
    if (i != extensions.size() - 1)
      ss << ", ";
  }
  ss << ']';

  ss << ", lntf: " << lntf.ToString();
  ss << ", nack: {rtp_history_ms: " << nack.rtp_history_ms << '}';
  ss << ", ulpfec: " << ulpfec.ToString();
  ss << ", payload_name: " << payload_name;
  ss << ", payload_type: " << payload_type;
  ss << ", raw_payload: " << (raw_payload ? "true" : "false");

  ss << ", stream_configs: [";
  for (size_t i = 0; i < stream_configs.size(); ++i) {
    ss << stream_configs[i].ToString();
    if (i != stream_configs.size() - 1)
      ss << ", ";
  }
  ss << ']';

  ss << ", flexfec: {payload_type: " << flexfec.payload_type;
  ss << ", ssrc: " << flexfec.ssrc;
  ss << ", protected_media_ssrcs: [";
  for (size_t i = 0; i < flexfec.protected_media_ssrcs.size(); ++i) {
    ss << flexfec.protected_media_ssrcs[i];
    if (i != flexfec.protected_media_ssrcs.size() - 1)
      ss << ", ";
  }
  ss << "]}";

  ss << ", rtx: " << rtx.ToString();
  ss << ", c_name: " << c_name;
  ss << '}';
  return ss.str();
}

RtpConfig::Rtx::Rtx() = default;
RtpConfig::Rtx::Rtx(const Rtx&) = default;
RtpConfig::Rtx::~Rtx() = default;

std::string RtpConfig::Rtx::ToString() const {
  char buf[1024];
  rtc::SimpleStringBuilder ss(buf);
  ss << "{ssrcs: [";
  for (size_t i = 0; i < ssrcs.size(); ++i) {
    ss << ssrcs[i];
    if (i != ssrcs.size() - 1)
      ss << ", ";
  }
  ss << ']';

  ss << ", payload_type: " << payload_type;
  ss << '}';
  return ss.str();
}

bool RtpConfig::IsMediaSsrc(uint32_t ssrc) const {
  return absl::c_linear_search(ssrcs, ssrc);
}

bool RtpConfig::IsRtxSsrc(uint32_t ssrc) const {
  return absl::c_linear_search(rtx.ssrcs, ssrc);
}

bool RtpConfig::IsFlexfecSsrc(uint32_t ssrc) const {
  return flexfec.payload_type != -1 && ssrc == flexfec.ssrc;
}

std::optional<uint32_t> RtpConfig::GetRtxSsrcAssociatedWithMediaSsrc(
    uint32_t media_ssrc) const {
  RTC_DCHECK(IsMediaSsrc(media_ssrc));
  // If we don't use RTX there is no association.
  if (rtx.ssrcs.empty())
    return std::nullopt;
  // If we use RTX there MUST be an association ssrcs[i] <-> rtx.ssrcs[i].
  RTC_DCHECK_EQ(ssrcs.size(), rtx.ssrcs.size());
  return FindAssociatedSsrc(media_ssrc, ssrcs, rtx.ssrcs);
}

uint32_t RtpConfig::GetMediaSsrcAssociatedWithRtxSsrc(uint32_t rtx_ssrc) const {
  RTC_DCHECK(IsRtxSsrc(rtx_ssrc));
  // If we use RTX there MUST be an association ssrcs[i] <-> rtx.ssrcs[i].
  RTC_DCHECK_EQ(ssrcs.size(), rtx.ssrcs.size());
  return FindAssociatedSsrc(rtx_ssrc, rtx.ssrcs, ssrcs);
}

uint32_t RtpConfig::GetMediaSsrcAssociatedWithFlexfecSsrc(
    uint32_t flexfec_ssrc) const {
  RTC_DCHECK(IsFlexfecSsrc(flexfec_ssrc));
  // If we use FlexFEC there MUST be an associated media ssrc.
  //
  // TODO(brandtr/hbos): The current implementation only supports an association
  // with a single media ssrc. If multiple ssrcs are to be supported in the
  // future, in order not to break GetStats()'s packet and byte counters, we
  // must be able to tell how many packets and bytes have contributed to which
  // SSRC.
  RTC_DCHECK_EQ(1u, flexfec.protected_media_ssrcs.size());
  uint32_t media_ssrc = flexfec.protected_media_ssrcs[0];
  RTC_DCHECK(IsMediaSsrc(media_ssrc));
  return media_ssrc;
}

std::optional<std::string> RtpConfig::GetRidForSsrc(uint32_t ssrc) const {
  auto it = std::find(ssrcs.begin(), ssrcs.end(), ssrc);
  if (it != ssrcs.end()) {
    size_t ssrc_index = std::distance(ssrcs.begin(), it);
    if (ssrc_index < rids.size()) {
      return rids[ssrc_index];
    }
  }
  return std::nullopt;
}

}  // namespace webrtc
