/*
 *  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 <algorithm>
#include <list>

#include "api/array_view.h"
#include "rtc_base/strings/string_builder.h"

namespace cricket {
namespace {
// NOTE: There is no check here for duplicate streams, so check before
// adding.
void AddStream(std::vector<StreamParams>* streams, const StreamParams& stream) {
  streams->push_back(stream);
}

std::string SsrcsToString(const std::vector<uint32_t>& ssrcs) {
  char buf[1024];
  rtc::SimpleStringBuilder sb(buf);
  sb << "ssrcs:[";
  for (std::vector<uint32_t>::const_iterator it = ssrcs.begin();
       it != ssrcs.end(); ++it) {
    if (it != ssrcs.begin()) {
      sb << ",";
    }
    sb << *it;
  }
  sb << "]";
  return sb.str();
}

std::string RidsToString(const std::vector<RidDescription>& rids) {
  char buf[1024];
  rtc::SimpleStringBuilder sb(buf);
  sb << "rids:[";
  const char* delimiter = "";
  for (const RidDescription& rid : rids) {
    sb << delimiter << rid.rid;
    delimiter = ",";
  }
  sb << "]";
  return sb.str();
}

}  // 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;
}

MediaStreams::MediaStreams() = default;
MediaStreams::~MediaStreams() = default;

bool MediaStreams::GetAudioStream(const StreamSelector& selector,
                                  StreamParams* stream) {
  return GetStream(audio_, selector, stream);
}

bool MediaStreams::GetVideoStream(const StreamSelector& selector,
                                  StreamParams* stream) {
  return GetStream(video_, selector, stream);
}

bool MediaStreams::GetDataStream(const StreamSelector& selector,
                                 StreamParams* stream) {
  return GetStream(data_, selector, stream);
}

void MediaStreams::CopyFrom(const MediaStreams& streams) {
  audio_ = streams.audio_;
  video_ = streams.video_;
  data_ = streams.data_;
}

void MediaStreams::AddAudioStream(const StreamParams& stream) {
  AddStream(&audio_, stream);
}

void MediaStreams::AddVideoStream(const StreamParams& stream) {
  AddStream(&video_, stream);
}

void MediaStreams::AddDataStream(const StreamParams& stream) {
  AddStream(&data_, stream);
}

bool MediaStreams::RemoveAudioStream(const StreamSelector& selector) {
  return RemoveStream(&audio_, selector);
}

bool MediaStreams::RemoveVideoStream(const StreamSelector& selector) {
  return RemoveStream(&video_, selector);
}

bool MediaStreams::RemoveDataStream(const StreamSelector& selector) {
  return RemoveStream(&data_, selector);
}

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 << ";";
  sb << SsrcsToString(ssrcs);
  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.
          rids_.size() == other.rids_.size() &&
          std::is_permutation(rids_.begin(), rids_.end(), other.rids_.begin()));
}

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 << ";";
  }
  sb << SsrcsToString(ssrcs) << ";";
  sb << "ssrc_groups:";
  for (std::vector<SsrcGroup>::const_iterator it = ssrc_groups.begin();
       it != ssrc_groups.end(); ++it) {
    if (it != ssrc_groups.begin()) {
      sb << ",";
    }
    sb << it->ToString();
  }
  sb << ";";
  if (!cname.empty()) {
    sb << "cname:" << cname << ";";
  }
  sb << "stream_ids:";
  for (std::vector<std::string>::const_iterator it = stream_ids_.begin();
       it != stream_ids_.end(); ++it) {
    if (it != stream_ids_.begin()) {
      sb << ",";
    }
    sb << *it;
  }
  sb << ";";
  if (!rids_.empty()) {
    sb << RidsToString(rids_) << ";";
  }
  sb << "}";
  return sb.str();
}
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 {
    for (size_t i = 0; i < sim_group->ssrcs.size(); ++i) {
      ssrcs->push_back(sim_group->ssrcs[i]);
    }
  }
}

void StreamParams::GetFidSsrcs(const std::vector<uint32_t>& primary_ssrcs,
                               std::vector<uint32_t>* fid_ssrcs) const {
  for (size_t i = 0; i < primary_ssrcs.size(); ++i) {
    uint32_t fid_ssrc;
    if (GetFidSsrc(primary_ssrcs[i], &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);
  std::vector<uint32_t> ssrc_vector;
  ssrc_vector.push_back(primary_ssrc);
  ssrc_vector.push_back(secondary_ssrc);
  SsrcGroup ssrc_group = SsrcGroup(semantics, ssrc_vector);
  ssrc_groups.push_back(ssrc_group);
  return true;
}

bool StreamParams::GetSecondarySsrc(const std::string& semantics,
                                    uint32_t primary_ssrc,
                                    uint32_t* secondary_ssrc) const {
  for (std::vector<SsrcGroup>::const_iterator it = ssrc_groups.begin();
       it != ssrc_groups.end(); ++it) {
    if (it->has_semantics(semantics) && it->ssrcs.size() >= 2 &&
        it->ssrcs[0] == primary_ssrc) {
      *secondary_ssrc = it->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];
}

bool IsOneSsrcStream(const StreamParams& sp) {
  if (sp.ssrcs.size() == 1 && sp.ssrc_groups.empty()) {
    return true;
  }
  const SsrcGroup* fid_group = sp.get_ssrc_group(kFidSsrcGroupSemantics);
  const SsrcGroup* fecfr_group = sp.get_ssrc_group(kFecFrSsrcGroupSemantics);
  if (sp.ssrcs.size() == 2) {
    if (fid_group != nullptr && sp.ssrcs == fid_group->ssrcs) {
      return true;
    }
    if (fecfr_group != nullptr && sp.ssrcs == fecfr_group->ssrcs) {
      return true;
    }
  }
  if (sp.ssrcs.size() == 3) {
    if (fid_group == nullptr || fecfr_group == nullptr) {
      return false;
    }
    if (sp.ssrcs[0] != fid_group->ssrcs[0] ||
        sp.ssrcs[0] != fecfr_group->ssrcs[0]) {
      return false;
    }
    // We do not check for FlexFEC over RTX,
    // as this combination is not supported.
    if (sp.ssrcs[1] == fid_group->ssrcs[1] &&
        sp.ssrcs[2] == fecfr_group->ssrcs[1]) {
      return true;
    }
    if (sp.ssrcs[1] == fecfr_group->ssrcs[1] &&
        sp.ssrcs[2] == fid_group->ssrcs[1]) {
      return true;
    }
  }
  return false;
}

namespace {
void RemoveFirst(std::list<uint32_t>* ssrcs, uint32_t value) {
  std::list<uint32_t>::iterator it =
      std::find(ssrcs->begin(), ssrcs->end(), value);
  if (it != ssrcs->end()) {
    ssrcs->erase(it);
  }
}
}  // namespace

bool IsSimulcastStream(const StreamParams& sp) {
  // Check for spec-compliant Simulcast using rids.
  if (sp.rids().size() > 1) {
    return true;
  }

  const SsrcGroup* const sg = sp.get_ssrc_group(kSimSsrcGroupSemantics);
  if (sg == NULL || sg->ssrcs.size() < 2) {
    return false;
  }
  // Start with all StreamParams SSRCs. Remove simulcast SSRCs (from sg) and
  // RTX SSRCs. If we still have SSRCs left, we don't know what they're for.
  // Also we remove first-found SSRCs only. So duplicates should lead to errors.
  std::list<uint32_t> sp_ssrcs(sp.ssrcs.begin(), sp.ssrcs.end());
  for (size_t i = 0; i < sg->ssrcs.size(); ++i) {
    RemoveFirst(&sp_ssrcs, sg->ssrcs[i]);
  }
  for (size_t i = 0; i < sp.ssrc_groups.size(); ++i) {
    const SsrcGroup& group = sp.ssrc_groups[i];
    if (group.semantics.compare(kFidSsrcGroupSemantics) != 0 ||
        group.ssrcs.size() != 2) {
      continue;
    }
    RemoveFirst(&sp_ssrcs, group.ssrcs[1]);
  }
  // If there's SSRCs left that we don't know how to handle, we bail out.
  return sp_ssrcs.size() == 0;
}

}  // namespace cricket
