/*
 *  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 <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/transport.h"
#include "api/crypto/crypto_options.h"
#include "api/environment/environment_factory.h"
#include "api/make_ref_counted.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 "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/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(
        CreateEnvironment(time_controller_.GetClock(), &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, &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() {
    RtpPacketReceived packet;
    packet.set_arrival_time(time_controller_.GetClock()->CurrentTime());
    packet.SetTimestamp(RtpNow());
    packet.SetSsrc(kLocalSsrc);
    packet.SetPayloadType(kPayloadType);
    // 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);
}

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