/*
 *  Copyright 2020 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 "pc/transceiver_list.h"

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

#include "absl/strings/string_view.h"
#include "api/rtp_parameters.h"
#include "api/rtp_sender_interface.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "pc/rtp_transceiver.h"
#include "rtc_base/checks.h"

namespace webrtc {

void TransceiverStableState::set_newly_created() {
  RTC_DCHECK(!has_m_section_);
  newly_created_ = true;
}

void TransceiverStableState::SetMSectionIfUnset(
    std::optional<std::string> mid,
    std::optional<size_t> mline_index) {
  if (!has_m_section_) {
    mid_ = mid;
    mline_index_ = mline_index;
    has_m_section_ = true;
  }
}

void TransceiverStableState::SetRemoteStreamIds(
    const std::vector<std::string>& ids) {
  if (!remote_stream_ids_.has_value()) {
    remote_stream_ids_ = ids;
  }
}

void TransceiverStableState::SetInitSendEncodings(
    std::vector<RtpEncodingParameters> encodings) {
  init_send_encodings_ = std::move(encodings);
}

std::vector<RtpTransceiver*> TransceiverList::ListInternal() const {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  std::vector<RtpTransceiver*> internals;
  internals.reserve(transceivers_.size());
  for (const auto& transceiver : transceivers_) {
    internals.push_back(transceiver->internal());
  }
  return internals;
}

RtpTransceiverProxyRefPtr TransceiverList::FindBySender(
    scoped_refptr<RtpSenderInterface> sender) const {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  for (const auto& transceiver : transceivers_) {
    if (transceiver->sender() == sender) {
      return transceiver;
    }
  }
  return nullptr;
}

RtpTransceiverProxyRefPtr TransceiverList::FindByMid(
    absl::string_view mid) const {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  for (const auto& transceiver : transceivers_) {
    if (transceiver->mid() == mid) {
      return transceiver;
    }
  }
  return nullptr;
}

RtpTransceiverProxyRefPtr TransceiverList::FindUnassociatedByMLineIndex(
    size_t mline_index) const {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  for (const auto& transceiver : transceivers_) {
    RtpTransceiver* internal = transceiver->internal();
    if (!internal->mid() && internal->mline_index() == mline_index) {
      return transceiver;
    }
  }
  return nullptr;
}

}  // namespace webrtc
