/*
 *  Copyright 2023 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 "audio/channel_receive.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <optional>
#include <span>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/audio/audio_frame.h"
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/call/audio_sink.h"
#include "api/call/transport.h"
#include "api/crypto/crypto_options.h"
#include "api/make_ref_counted.h"
#include "api/rtp_packet_infos.h"
#include "api/scoped_refptr.h"
#include "api/test/mock_frame_transformer.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "call/syncable.h"
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
#include "modules/audio_device/include/mock_audio_device.h"
#include "modules/pacing/packet_router.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/ntp_time_util.h"
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/logging.h"
#include "rtc_base/string_encode.h"
#include "system_wrappers/include/ntp_time.h"
#include "test/create_test_environment.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/mock_transport.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {
namespace voe {
namespace {

using ::testing::NiceMock;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::Test;

constexpr uint32_t kLocalSsrc = kFallbackRtcpSsrcForAudio;
constexpr uint32_t kRemoteSsrc = 2222;
// We run RTP data with 8 kHz PCMA (fixed payload type 8).
constexpr char kPayloadName[] = "PCMA";
constexpr int kPayloadType = 8;
constexpr int kSampleRateHz = 8000;

class ChannelReceiveTest : public Test {
 public:
  ChannelReceiveTest()
      : time_controller_(Timestamp::Seconds(5555)),
        audio_device_module_(test::MockAudioDeviceModule::CreateNice()),
        audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()) {
    ON_CALL(*audio_device_module_, PlayoutDelay).WillByDefault(Return(0));
  }

  std::unique_ptr<ChannelReceiveInterface> CreateTestChannelReceive() {
    CryptoOptions crypto_options;
    auto channel = CreateChannelReceive(
        CreateTestEnvironment({.time = &time_controller_, .event_log = &log_}),
        /* neteq_factory= */ nullptr, audio_device_module_.get(), &transport_,
        kRemoteSsrc,
        /* jitter_buffer_max_packets= */ 0,
        /* jitter_buffer_fast_playout= */ false,
        /* jitter_buffer_min_delay_ms= */ 0,
        /* enable_non_sender_rtt= */ false, audio_decoder_factory_,
        /* frame_decryptor_interface= */ nullptr, crypto_options,
        /* frame_transformer= */ nullptr,
        /* on_first_packet= */ nullptr, &packet_router_);
    channel->SetReceiveCodecs(
        {{kPayloadType, {kPayloadName, kSampleRateHz, 1}}});
    return channel;
  }

  NtpTime NtpNow() { return time_controller_.GetClock()->CurrentNtpTime(); }

  uint32_t RtpNow() {
    // Note - the "random" offset of this timestamp is zero.
    return time_controller_.GetClock()->TimeInMilliseconds() * 1000 /
           kSampleRateHz;
  }

  RtpPacketReceived CreateRtpPacket(std::span<const uint32_t> csrcs = {}) {
    RtpPacketReceived packet;
    packet.set_arrival_time(time_controller_.GetClock()->CurrentTime());
    packet.SetTimestamp(RtpNow());
    packet.SetSsrc(kLocalSsrc);
    packet.SetPayloadType(kPayloadType);
    if (!csrcs.empty()) {
      packet.SetCsrcs(csrcs);
    }
    // Packet size should be enough to give at least 10 ms of data.
    // For PCMA, that's 80 bytes; this should be enough.
    uint8_t* datapos = packet.SetPayloadSize(100);
    memset(datapos, 0, 100);
    return packet;
  }

  std::vector<uint8_t> CreateRtcpSenderReport() {
    std::vector<uint8_t> packet(1024);
    size_t pos = 0;
    rtcp::SenderReport report;
    report.SetSenderSsrc(kRemoteSsrc);
    report.SetNtp(NtpNow());
    report.SetRtpTimestamp(RtpNow());
    report.SetPacketCount(0);
    report.SetOctetCount(0);
    report.Create(&packet[0], &pos, packet.size(), nullptr);
    // No report blocks.
    packet.resize(pos);
    return packet;
  }

  std::vector<uint8_t> CreateRtcpReceiverReport() {
    rtcp::ReportBlock block;
    block.SetMediaSsrc(kLocalSsrc);
    // Middle 32 bits of the NTP timestamp from received SR
    block.SetLastSr(CompactNtp(NtpNow()));
    block.SetDelayLastSr(0);

    rtcp::ReceiverReport report;
    report.SetSenderSsrc(kRemoteSsrc);
    report.AddReportBlock(block);

    std::vector<uint8_t> packet(1024);
    size_t pos = 0;
    report.Create(&packet[0], &pos, packet.size(), nullptr);
    packet.resize(pos);
    return packet;
  }

  void HandleGeneratedRtcp(ChannelReceiveInterface& /* channel */,
                           std::span<const uint8_t> packet) {
    if (packet[1] == rtcp::ReceiverReport::kPacketType) {
      // Ignore RR, it requires no response
    } else {
      RTC_LOG(LS_ERROR) << "Unexpected RTCP packet generated";
      RTC_LOG(LS_ERROR) << "Packet content "
                        << hex_encode_with_delimiter(
                               absl::string_view(
                                   reinterpret_cast<char*>(packet.data()[0]),
                                   packet.size()),
                               ' ');
    }
  }

  int64_t ProbeCaptureStartNtpTime(ChannelReceiveInterface& channel) {
    // Computation of the capture_start_ntp_time_ms_ occurs when the
    // audio data is pulled, not when it is received. So we need to
    // inject an RTP packet, and then fetch its data.
    AudioFrame audio_frame;
    channel.OnRtpPacket(CreateRtpPacket());
    channel.GetAudioFrameWithInfo(kSampleRateHz, &audio_frame);
    ChannelReceiveStatistics stats = channel.GetRTCPStatistics();
    return stats.capture_start_ntp_time_ms;
  }

 protected:
  GlobalSimulatedTimeController time_controller_;
  NiceMock<MockRtcEventLog> log_;
  scoped_refptr<test::MockAudioDeviceModule> audio_device_module_;
  scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
  MockTransport transport_;
  PacketRouter packet_router_;
};

TEST_F(ChannelReceiveTest, CreateAndDestroy) {
  auto channel = CreateTestChannelReceive();
  EXPECT_THAT(channel, NotNull());
}

TEST_F(ChannelReceiveTest, ReceiveReportGeneratedOnTime) {
  auto channel = CreateTestChannelReceive();

  bool receiver_report_sent = false;
  EXPECT_CALL(transport_, SendRtcp)
      .WillRepeatedly([&](std::span<const uint8_t> packet,
                          const PacketOptions& options) {
        if (packet.size() >= 2 &&
            packet[1] == rtcp::ReceiverReport::kPacketType) {
          receiver_report_sent = true;
        }
        return true;
      });
  // RFC 3550 section 6.2 mentions 5 seconds as a reasonable expectation
  // for the interval between RTCP packets.
  time_controller_.AdvanceTime(TimeDelta::Seconds(5));

  EXPECT_TRUE(receiver_report_sent);
}

TEST_F(ChannelReceiveTest, CaptureStartTimeBecomesValid) {
  auto channel = CreateTestChannelReceive();

  EXPECT_CALL(transport_, SendRtcp)
      .WillRepeatedly(
          [&](std::span<const uint8_t> packet, const PacketOptions& options) {
            HandleGeneratedRtcp(*channel, packet);
            return true;
          });
  // Before any packets are sent, CaptureStartTime is invalid.
  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);

  // Must start playout, otherwise packet is discarded.
  channel->StartPlayout();
  // Send one RTP packet. This causes registration of the SSRC.
  channel->OnRtpPacket(CreateRtpPacket());
  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);

  // Receive a sender report.
  auto rtcp_packet_1 = CreateRtcpSenderReport();
  channel->ReceivedRTCPPacket(rtcp_packet_1.data(), rtcp_packet_1.size());
  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);

  time_controller_.AdvanceTime(TimeDelta::Seconds(5));

  // Receive a receiver report. This is necessary, which is odd.
  // Presumably it is because the receiver needs to know the RTT
  // before it can compute the capture start NTP time.
  // The receiver report must happen before the second sender report.
  auto rtcp_rr = CreateRtcpReceiverReport();
  channel->ReceivedRTCPPacket(rtcp_rr.data(), rtcp_rr.size());
  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);

  // Receive another sender report after 5 seconds.
  // This should be enough to establish the capture start NTP time.
  auto rtcp_packet_2 = CreateRtcpSenderReport();
  channel->ReceivedRTCPPacket(rtcp_packet_2.data(), rtcp_packet_2.size());

  EXPECT_NE(ProbeCaptureStartNtpTime(*channel), -1);
}

TEST_F(ChannelReceiveTest, SettingFrameTransformer) {
  auto channel = CreateTestChannelReceive();

  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
      make_ref_counted<MockFrameTransformer>();

  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback);
  channel->SetDepacketizerToDecoderFrameTransformer(mock_frame_transformer);

  // Must start playout, otherwise packet is discarded.
  channel->StartPlayout();

  RtpPacketReceived packet = CreateRtpPacket();

  // Receive one RTP packet, this should be transformed.
  EXPECT_CALL(*mock_frame_transformer, Transform);
  channel->OnRtpPacket(packet);
}

TEST_F(ChannelReceiveTest, SettingFrameTransformerMultipleTimes) {
  auto channel = CreateTestChannelReceive();

  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
      make_ref_counted<MockFrameTransformer>();

  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback);
  channel->SetDepacketizerToDecoderFrameTransformer(mock_frame_transformer);

  // Set the same transformer again, shouldn't cause any additional callback
  // registration calls.
  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
      .Times(0);
  channel->SetDepacketizerToDecoderFrameTransformer(mock_frame_transformer);
}

TEST_F(ChannelReceiveTest, LogsReceivedPacketToEventLog) {
  auto channel = CreateTestChannelReceive();

  RtpPacketReceived packet = CreateRtpPacket();

  EXPECT_CALL(log_, LogProxy);
  channel->OnRtpPacket(packet);
}

TEST_F(ChannelReceiveTest, GetPlayoutRtpTimestamp) {
  auto channel = CreateTestChannelReceive();

  // Before playout starts, no timestamp is available.
  EXPECT_FALSE(channel->GetPlayoutRtpTimestamp().has_value());

  channel->StartPlayout();
  // Playout started, but no audio frames have been pulled yet.
  EXPECT_FALSE(channel->GetPlayoutRtpTimestamp().has_value());

  // Deliver an RTP packet and pull an audio frame.
  channel->OnRtpPacket(CreateRtpPacket());
  AudioFrame audio_frame;
  channel->GetAudioFrameWithInfo(kSampleRateHz, &audio_frame);

  Timestamp playout_time = time_controller_.GetClock()->CurrentTime();
  std::optional<Syncable::PlayoutInfo> playout_info =
      channel->GetPlayoutRtpTimestamp();
  ASSERT_TRUE(playout_info.has_value());
  EXPECT_EQ(playout_info->time, playout_time);

  // Stopping playout clears playout timestamp.
  channel->StopPlayout();
  EXPECT_FALSE(channel->GetPlayoutRtpTimestamp().has_value());

  // Restarting playout requires pulling another frame.
  channel->StartPlayout();
  EXPECT_FALSE(channel->GetPlayoutRtpTimestamp().has_value());

  channel->OnRtpPacket(CreateRtpPacket());
  channel->GetAudioFrameWithInfo(kSampleRateHz, &audio_frame);
  playout_time = time_controller_.GetClock()->CurrentTime();
  playout_info = channel->GetPlayoutRtpTimestamp();
  ASSERT_TRUE(playout_info.has_value());
  EXPECT_EQ(playout_info->time, playout_time);

  // Stopping playout clears playout timestamp.
  channel->StopPlayout();
  EXPECT_FALSE(channel->GetPlayoutRtpTimestamp().has_value());
}

TEST_F(ChannelReceiveTest, AudioSinkReceivesPacketInfos) {
  class TestAudioSink : public AudioSinkInterface {
   public:
    void OnData(const Data& audio) override {
      data_called_ = true;
      if (audio.packet_infos != nullptr) {
        last_packet_infos_ = *audio.packet_infos;
      }
    }
    bool data_called_ = false;
    RtpPacketInfos last_packet_infos_;
  };

  auto channel = CreateTestChannelReceive();
  TestAudioSink sink;
  channel->SetSink(&sink);
  channel->StartPlayout();

  const uint32_t kCsrcs[] = {1111, 2222};
  channel->OnRtpPacket(CreateRtpPacket(kCsrcs));

  AudioFrame audio_frame;
  channel->GetAudioFrameWithInfo(kSampleRateHz, &audio_frame);

  EXPECT_TRUE(sink.data_called_);
  ASSERT_EQ(sink.last_packet_infos_.size(), 1u);
  EXPECT_THAT(sink.last_packet_infos_[0].csrcs(),
              ::testing::ElementsAre(1111, 2222));
}

}  // namespace
}  // namespace voe
}  // namespace webrtc
