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

#ifndef PC_CODEC_VENDOR_H_
#define PC_CODEC_VENDOR_H_

#include <span>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/strings/string_view.h"
#include "api/field_trials_view.h"
#include "api/media_types.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/rtp_transceiver_direction.h"
#include "api/sequence_checker.h"
#include "call/payload_type.h"
#include "media/base/codec.h"
#include "media/base/codec_list.h"
#include "media/base/media_engine.h"
#include "pc/media_options.h"
#include "pc/session_description.h"
#include "pc/typed_codec_vendor.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

// This class contains the functions required to compute the list of codecs
// for SDP offer/answer. It is exposed to MediaSessionDescriptionFactory
// for the construction of offers and answers.

// TODO: bugs.webrtc.org/360058654 - complete the architectural changes
// The list of things to be done:
// - Make as much as possible private.
// - Make state const where possible while updates related to threading are
// being done.
// - Remove test code from the implementation.
// - Split object usage into four objects: sender/receiver/audio/video.
// - Remove audio/video from the call names, merge code where possible.
// - Make the class instances owned by transceivers, so that codec
//   lists can differ per transceiver.
// For cleanliness:
// - Thread guard
// For performance:
// - Ensure that no blocking calls are made.
class CodecVendor {
 public:
  // A null media_engine is permitted in order to allow unit testing where the
  // codecs are explicitly set by the test.
  // TODO: bugs.webrtc.org/360058654 - The tests can accomplish what they need
  // by using the same interface as is used in production.
  // Update the tests instead to supply a valid MediaEngineInterface object
  // and rather test how CodecVendor works regularly.
  CodecVendor(const MediaEngineInterface* absl_nullable media_engine,
              bool rtx_enabled,
              const FieldTrialsView& trials);

  RTCErrorOr<std::vector<Codec>> GetNegotiatedCodecsForOffer(
      const MediaDescriptionOptions& media_description_options,
      const MediaSessionOptions& session_options,
      const ContentInfo* current_content,
      PayloadTypeSuggester& pt_suggester);

  RTCErrorOr<Codecs> GetNegotiatedCodecsForAnswer(
      const MediaDescriptionOptions& media_description_options,
      const MediaSessionOptions& session_options,
      RtpTransceiverDirection offer_rtd,
      RtpTransceiverDirection answer_rtd,
      const ContentInfo* current_content,
      std::span<const Codec> codecs_from_offer,
      PayloadTypeSuggester& pt_suggester);

  // Function exposed for issues.webrtc.org/412904801
  // Modify the video codecs to return on subsequent GetNegotiated* calls.
  // The input is a vector of pairs of codecs.
  // For each pair, the first element is the codec to be replaced,
  // and the second element is the codec to replace it with.
  void ModifyVideoCodecs(const std::vector<std::pair<Codec, Codec>>& changes);

  // Workaround for issues.webrtc.org/412904801.
  // Specifically sets packetization to "raw" for the matching codec in
  // configurations_, to support the packetization=raw hack applied via SDP
  // munging.
  void SetRawPacketization(const Codec& codec);

  bool payload_types_in_transport() const {
    return payload_types_in_transport_;
  }

  // Functions exposed for testing
  CodecList audio_sendrecv_codecs() const;
  const CodecList& audio_send_codecs() const;
  const CodecList& audio_recv_codecs() const;
  CodecList video_sendrecv_codecs() const;
  const CodecList& video_send_codecs() const;
  const CodecList& video_recv_codecs() const;

 private:
  CodecList GetAudioCodecsForOffer(
      const RtpTransceiverDirection& direction) const;
  CodecList GetAudioCodecsForAnswer(
      const RtpTransceiverDirection& offer,
      const RtpTransceiverDirection& answer) const;
  CodecList GetVideoCodecsForOffer(
      const RtpTransceiverDirection& direction) const;
  CodecList GetVideoCodecsForAnswer(
      const RtpTransceiverDirection& offer,
      const RtpTransceiverDirection& answer) const;

  RTCError MergeAndAssignConfiguredCodecs(
      MediaType type,
      RtpTransceiverDirection direction,
      absl::string_view mid,
      CodecList& codecs_out,
      PayloadTypeSuggester& pt_suggester,
      bool pick_from_top_of_range,
      std::span<const RtpCodecCapability> codec_preferences = {},
      bool vad_enabled = true);

  // Makes sure that modifications and reading data is done on the same thread
  // and to makessure we consistently make calls to GetNegotiatedCodecsForOffer
  // and GetNegotiatedCodecsForAnswer in the same calling context.
  RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;

  const FieldTrialsView& trials_;

  const TypedCodecVendor audio_send_codecs_;
  const TypedCodecVendor audio_recv_codecs_;

  const bool payload_types_in_transport_;

  // TODO: bugs.webrtc.org/412904801 - Make const. In order to be able to do
  // that, `ModifyVideoCodecs` needs to be removed. In the meantime, codec
  // information must be read and modified on the same task queue.
  TypedCodecVendor video_send_codecs_ RTC_GUARDED_BY(sequence_checker_);
  TypedCodecVendor video_recv_codecs_ RTC_GUARDED_BY(sequence_checker_);
};

// A class to assist in looking up data for a codec mapping.
// Pure virtual to allow implementations that depend on things that
// codec_vendor.h should not depend on.
// Pointers returned are not stable, and should not be stored.
class CodecLookupHelper {
 public:
  virtual ~CodecLookupHelper() = default;
  virtual ::webrtc::PayloadTypeSuggester* PayloadTypeSuggester() = 0;
  // Look up the codec vendor to use, depending on context.
  // This call may get additional arguments in the future, to aid
  // in selection of the correct context.
  virtual CodecVendor* GetCodecVendor() = 0;
};

// A helper function to merge codecs numbered in one PT numberspace
// into a list numbered in another PT numberspace. Exposed for testing.
// This function is only available for testing the legacy path.
RTCError MergeCodecsForTesting(const CodecList& reference_codecs,
                               absl::string_view mid,
                               CodecList& offered_codecs,
                               PayloadTypeSuggester& pt_suggester,
                               bool pick_from_top_of_range = false);

}  //  namespace webrtc

#endif  // PC_CODEC_VENDOR_H_
