/*
 *  Copyright (c) 2011 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 "media/base/stream_params.h"

#include <stdint.h>
#include <list>

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

namespace cricket {
namespace {

void AppendSsrcs(rtc::ArrayView<const uint32_t> ssrcs,
                 rtc::SimpleStringBuilder* sb) {
  *sb << "ssrcs:[";
  const char* delimiter = "";
  for (uint32_t ssrc : ssrcs) {
    *sb << delimiter << ssrc;
    delimiter = ",";
  }
  *sb << "]";
}

void AppendSsrcGroups(rtc::ArrayView<const SsrcGroup> ssrc_groups,
                      rtc::SimpleStringBuilder* sb) {
  *sb << "ssrc_groups:";
  const char* delimiter = "";
  for (const SsrcGroup& ssrc_group : ssrc_groups) {
    *sb << delimiter << ssrc_group.ToString();
    delimiter = ",";
  }
}

void AppendStreamIds(rtc::ArrayView<const std::string> stream_ids,
                     rtc::SimpleStringBuilder* sb) {
  *sb << "stream_ids:";
  const char* delimiter = "";
  for (const std::string& stream_id : stream_ids) {
    *sb << delimiter << stream_id;
    delimiter = ",";
  }
}

void AppendRids(rtc::ArrayView<const RidDescription> rids,
                rtc::SimpleStringBuilder* sb) {
  *sb << "rids:[";
  const char* delimiter = "";
  for (const RidDescription& rid : rids) {
    *sb << delimiter << rid.rid;
    delimiter = ",";
  }
  *sb << "]";
}

}  // namespace

const char kFecSsrcGroupSemantics[] = "FEC";
const char kFecFrSsrcGroupSemantics[] = "FEC-FR";
const char kFidSsrcGroupSemantics[] = "FID";
const char kSimSsrcGroupSemantics[] = "SIM";

bool GetStream(const StreamParamsVec& streams,
               const StreamSelector& selector,
               StreamParams* stream_out) {
  const StreamParams* found = GetStream(streams, selector);
  if (found && stream_out)
    *stream_out = *found;
  return found != nullptr;
}

SsrcGroup::SsrcGroup(const std::string& usage,
                     const std::vector<uint32_t>& ssrcs)
    : semantics(usage), ssrcs(ssrcs) {}
SsrcGroup::SsrcGroup(const SsrcGroup&) = default;
SsrcGroup::SsrcGroup(SsrcGroup&&) = default;
SsrcGroup::~SsrcGroup() = default;

SsrcGroup& SsrcGroup::operator=(const SsrcGroup&) = default;
SsrcGroup& SsrcGroup::operator=(SsrcGroup&&) = default;

bool SsrcGroup::has_semantics(const std::string& semantics_in) const {
  return (semantics == semantics_in && ssrcs.size() > 0);
}

std::string SsrcGroup::ToString() const {
  char buf[1024];
  rtc::SimpleStringBuilder sb(buf);
  sb << "{";
  sb << "semantics:" << semantics << ";";
  AppendSsrcs(ssrcs, &sb);
  sb << "}";
  return sb.str();
}

StreamParams::StreamParams() = default;
StreamParams::StreamParams(const StreamParams&) = default;
StreamParams::StreamParams(StreamParams&&) = default;
StreamParams::~StreamParams() = default;
StreamParams& StreamParams::operator=(const StreamParams&) = default;
StreamParams& StreamParams::operator=(StreamParams&&) = default;

bool StreamParams::operator==(const StreamParams& other) const {
  return (groupid == other.groupid && id == other.id && ssrcs == other.ssrcs &&
          ssrc_groups == other.ssrc_groups && cname == other.cname &&
          stream_ids_ == other.stream_ids_ &&
          // RIDs are not required to be in the same order for equality.
          absl::c_is_permutation(rids_, other.rids_));
}

std::string StreamParams::ToString() const {
  char buf[2 * 1024];
  rtc::SimpleStringBuilder sb(buf);
  sb << "{";
  if (!groupid.empty()) {
    sb << "groupid:" << groupid << ";";
  }
  if (!id.empty()) {
    sb << "id:" << id << ";";
  }
  AppendSsrcs(ssrcs, &sb);
  sb << ";";
  AppendSsrcGroups(ssrc_groups, &sb);
  sb << ";";
  if (!cname.empty()) {
    sb << "cname:" << cname << ";";
  }
  AppendStreamIds(stream_ids_, &sb);
  sb << ";";
  if (!rids_.empty()) {
    AppendRids(rids_, &sb);
    sb << ";";
  }
  sb << "}";
  return sb.str();
}

void StreamParams::GenerateSsrcs(int num_layers,
                                 bool generate_fid,
                                 bool generate_fec_fr,
                                 rtc::UniqueRandomIdGenerator* ssrc_generator) {
  RTC_DCHECK_GE(num_layers, 0);
  RTC_DCHECK(ssrc_generator);
  std::vector<uint32_t> primary_ssrcs;
  for (int i = 0; i < num_layers; ++i) {
    uint32_t ssrc = ssrc_generator->GenerateId();
    primary_ssrcs.push_back(ssrc);
    add_ssrc(ssrc);
  }

  if (num_layers > 1) {
    SsrcGroup simulcast(kSimSsrcGroupSemantics, primary_ssrcs);
    ssrc_groups.push_back(simulcast);
  }

  if (generate_fid) {
    for (uint32_t ssrc : primary_ssrcs) {
      AddFidSsrc(ssrc, ssrc_generator->GenerateId());
    }
  }

  if (generate_fec_fr) {
    for (uint32_t ssrc : primary_ssrcs) {
      AddFecFrSsrc(ssrc, ssrc_generator->GenerateId());
    }
  }
}

void StreamParams::GetPrimarySsrcs(std::vector<uint32_t>* ssrcs) const {
  const SsrcGroup* sim_group = get_ssrc_group(kSimSsrcGroupSemantics);
  if (sim_group == NULL) {
    ssrcs->push_back(first_ssrc());
  } else {
    ssrcs->insert(ssrcs->end(), sim_group->ssrcs.begin(),
                  sim_group->ssrcs.end());
  }
}

void StreamParams::GetFidSsrcs(const std::vector<uint32_t>& primary_ssrcs,
                               std::vector<uint32_t>* fid_ssrcs) const {
  for (uint32_t primary_ssrc : primary_ssrcs) {
    uint32_t fid_ssrc;
    if (GetFidSsrc(primary_ssrc, &fid_ssrc)) {
      fid_ssrcs->push_back(fid_ssrc);
    }
  }
}

bool StreamParams::AddSecondarySsrc(const std::string& semantics,
                                    uint32_t primary_ssrc,
                                    uint32_t secondary_ssrc) {
  if (!has_ssrc(primary_ssrc)) {
    return false;
  }

  ssrcs.push_back(secondary_ssrc);
  ssrc_groups.push_back(SsrcGroup(semantics, {primary_ssrc, secondary_ssrc}));
  return true;
}

bool StreamParams::GetSecondarySsrc(const std::string& semantics,
                                    uint32_t primary_ssrc,
                                    uint32_t* secondary_ssrc) const {
  for (const SsrcGroup& ssrc_group : ssrc_groups) {
    if (ssrc_group.has_semantics(semantics) && ssrc_group.ssrcs.size() >= 2 &&
        ssrc_group.ssrcs[0] == primary_ssrc) {
      *secondary_ssrc = ssrc_group.ssrcs[1];
      return true;
    }
  }
  return false;
}

std::vector<std::string> StreamParams::stream_ids() const {
  return stream_ids_;
}

void StreamParams::set_stream_ids(const std::vector<std::string>& stream_ids) {
  stream_ids_ = stream_ids;
}

std::string StreamParams::first_stream_id() const {
  return stream_ids_.empty() ? "" : stream_ids_[0];
}

}  // namespace cricket
