/*
 *  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/rtx_receive_stream.h"

#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <span>
#include <utility>

#include "api/environment/environment.h"
#include "api/sequence_checker.h"
#include "call/rtp_packet_sink_interface.h"
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
#include "modules/rtp_rtcp/include/receive_statistics.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

// Deprecated, don't use.
RtxReceiveStream::RtxReceiveStream(
    RtpPacketSinkInterface* media_sink,
    std::map<int, int> associated_payload_types,
    uint32_t media_ssrc,
    ReceiveStatistics* rtp_receive_statistics /* = nullptr */)
    : env_(std::nullopt),
      media_sink_(media_sink),
      associated_payload_types_(std::move(associated_payload_types)),
      media_ssrc_(media_ssrc),
      rtp_receive_statistics_(rtp_receive_statistics) {
  packet_checker_.Detach();
  if (associated_payload_types_.empty()) {
    RTC_LOG(LS_WARNING)
        << "RtxReceiveStream created with empty payload type mapping.";
  }
}

RtxReceiveStream::RtxReceiveStream(
    const Environment& env,
    RtpPacketSinkInterface* media_sink,
    std::map<int, int> associated_payload_types,
    uint32_t media_ssrc,
    ReceiveStatistics* rtp_receive_statistics /* = nullptr */)
    : env_(env),
      media_sink_(media_sink),
      associated_payload_types_(std::move(associated_payload_types)),
      media_ssrc_(media_ssrc),
      rtp_receive_statistics_(rtp_receive_statistics) {
  packet_checker_.Detach();
  if (associated_payload_types_.empty()) {
    RTC_LOG(LS_WARNING)
        << "RtxReceiveStream created with empty payload type mapping.";
  }
}

RtxReceiveStream::~RtxReceiveStream() = default;

void RtxReceiveStream::SetAssociatedPayloadTypes(
    std::map<int, int> associated_payload_types) {
  RTC_DCHECK_RUN_ON(&packet_checker_);
  associated_payload_types_ = std::move(associated_payload_types);
}

void RtxReceiveStream::OnRtpPacket(const RtpPacketReceived& rtx_packet) {
  RTC_DCHECK_RUN_ON(&packet_checker_);
  if (rtp_receive_statistics_) {
    rtp_receive_statistics_->OnRtpPacket(rtx_packet);
  }
  std::span<const uint8_t> payload = rtx_packet.payload();

  if (payload.size() < kRtxHeaderSize) {
    LogRtpPacketToEventLog(rtx_packet, /*osn=*/std::nullopt);
    return;
  }

  auto it = associated_payload_types_.find(rtx_packet.PayloadType());
  if (it == associated_payload_types_.end()) {
    RTC_DLOG(LS_VERBOSE) << "Unknown payload type "
                         << static_cast<int>(rtx_packet.PayloadType())
                         << " on rtx ssrc " << rtx_packet.Ssrc();
    LogRtpPacketToEventLog(rtx_packet, /*osn=*/std::nullopt);
    return;
  }

  RTC_DCHECK_GE(payload.size(), 2);
  // The RTX payload header is two bytes that represents the original sequence
  // number ('osn') of the associated original packet.
  // https://datatracker.ietf.org/doc/html/rfc4588#section-4
  uint16_t osn = (payload[0] << 8) + payload[1];
  LogRtpPacketToEventLog(rtx_packet, osn);

  RtpPacketReceived media_packet;
  media_packet.CopyHeaderFrom(rtx_packet);

  media_packet.SetSsrc(media_ssrc_);
  media_packet.SetSequenceNumber(osn);
  media_packet.SetPayloadType(it->second);
  media_packet.set_recovered(true);
  media_packet.set_arrival_time(rtx_packet.arrival_time());

  // Skip the RTX payload header.
  media_packet.SetPayload(payload.subspan(kRtxHeaderSize));

  media_sink_->OnRtpPacket(media_packet);
}

void RtxReceiveStream::LogRtpPacketToEventLog(const RtpPacketReceived& packet,
                                              std::optional<uint16_t> osn) {
  if (!env_) {
    return;
  }
  env_->event_log().Log(
      std::make_unique<RtcEventRtpPacketIncoming>(packet, osn));
}

}  // namespace webrtc
