/*
 *  Copyright (c) 2012 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 "modules/rtp_rtcp/test/testAPI/test_api.h"

#include <algorithm>
#include <memory>
#include <vector>

#include "rtc_base/checks.h"
#include "rtc_base/rate_limiter.h"
#include "test/null_transport.h"

namespace webrtc {

void LoopBackTransport::SetSendModule(RtpRtcp* rtp_rtcp_module,
                                      RTPPayloadRegistry* payload_registry,
                                      RtpReceiver* receiver,
                                      ReceiveStatistics* receive_statistics) {
  rtp_rtcp_module_ = rtp_rtcp_module;
  rtp_payload_registry_ = payload_registry;
  rtp_receiver_ = receiver;
  receive_statistics_ = receive_statistics;
}

void LoopBackTransport::DropEveryNthPacket(int n) {
  packet_loss_ = n;
}

bool LoopBackTransport::SendRtp(const uint8_t* data,
                                size_t len,
                                const PacketOptions& options) {
  count_++;
  if (packet_loss_ > 0) {
    if ((count_ % packet_loss_) == 0) {
      return true;
    }
  }
  RTPHeader header;
  std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
  if (!parser->Parse(data, len, &header)) {
    return false;
  }
  const auto pl =
      rtp_payload_registry_->PayloadTypeToPayload(header.payloadType);
  if (!pl) {
    return false;
  }
  const uint8_t* payload = data + header.headerLength;
  RTC_CHECK_GE(len, header.headerLength);
  const size_t payload_length = len - header.headerLength;
  receive_statistics_->IncomingPacket(header, len, false);
  return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
                                          pl->typeSpecific);
}

bool LoopBackTransport::SendRtcp(const uint8_t* data, size_t len) {
  rtp_rtcp_module_->IncomingRtcpPacket((const uint8_t*)data, len);
  return true;
}

int32_t TestRtpReceiver::OnReceivedPayloadData(
    const uint8_t* payload_data,
    size_t payload_size,
    const webrtc::WebRtcRTPHeader* rtp_header) {
  EXPECT_LE(payload_size, sizeof(payload_data_));
  memcpy(payload_data_, payload_data, payload_size);
  memcpy(&rtp_header_, rtp_header, sizeof(rtp_header_));
  payload_size_ = payload_size;
  return 0;
}

class RtpRtcpAPITest : public ::testing::Test {
 protected:
  RtpRtcpAPITest()
      : fake_clock_(123456), retransmission_rate_limiter_(&fake_clock_, 1000) {
    test_csrcs_.push_back(1234);
    test_csrcs_.push_back(2345);
    test_ssrc_ = 3456;
    test_timestamp_ = 4567;
    test_sequence_number_ = 2345;
  }
  ~RtpRtcpAPITest() {}

  const uint32_t initial_ssrc = 8888;

  void SetUp() override {
    RtpRtcp::Configuration configuration;
    configuration.audio = true;
    configuration.clock = &fake_clock_;
    configuration.outgoing_transport = &null_transport_;
    configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
    module_.reset(RtpRtcp::CreateRtpRtcp(configuration));
    module_->SetSSRC(initial_ssrc);
    rtp_payload_registry_.reset(new RTPPayloadRegistry());
  }

  std::unique_ptr<RTPPayloadRegistry> rtp_payload_registry_;
  std::unique_ptr<RtpRtcp> module_;
  uint32_t test_ssrc_;
  uint32_t test_timestamp_;
  uint16_t test_sequence_number_;
  std::vector<uint32_t> test_csrcs_;
  SimulatedClock fake_clock_;
  test::NullTransport null_transport_;
  RateLimiter retransmission_rate_limiter_;
};

TEST_F(RtpRtcpAPITest, Basic) {
  module_->SetSequenceNumber(test_sequence_number_);
  EXPECT_EQ(test_sequence_number_, module_->SequenceNumber());

  module_->SetStartTimestamp(test_timestamp_);
  EXPECT_EQ(test_timestamp_, module_->StartTimestamp());

  EXPECT_FALSE(module_->Sending());
  EXPECT_EQ(0, module_->SetSendingStatus(true));
  EXPECT_TRUE(module_->Sending());
}

TEST_F(RtpRtcpAPITest, PacketSize) {
  module_->SetMaxRtpPacketSize(1234);
  EXPECT_EQ(1234u, module_->MaxRtpPacketSize());
}

TEST_F(RtpRtcpAPITest, SSRC) {
  module_->SetSSRC(test_ssrc_);
  EXPECT_EQ(test_ssrc_, module_->SSRC());
}

TEST_F(RtpRtcpAPITest, RTCP) {
  EXPECT_EQ(RtcpMode::kOff, module_->RTCP());
  module_->SetRTCPStatus(RtcpMode::kCompound);
  EXPECT_EQ(RtcpMode::kCompound, module_->RTCP());

  EXPECT_EQ(0, module_->SetCNAME("john.doe@test.test"));

  EXPECT_FALSE(module_->TMMBR());
  module_->SetTMMBRStatus(true);
  EXPECT_TRUE(module_->TMMBR());
  module_->SetTMMBRStatus(false);
  EXPECT_FALSE(module_->TMMBR());
}

TEST_F(RtpRtcpAPITest, RtxSender) {
  module_->SetRtxSendStatus(kRtxRetransmitted);
  EXPECT_EQ(kRtxRetransmitted, module_->RtxSendStatus());

  module_->SetRtxSendStatus(kRtxOff);
  EXPECT_EQ(kRtxOff, module_->RtxSendStatus());

  module_->SetRtxSendStatus(kRtxRetransmitted);
  EXPECT_EQ(kRtxRetransmitted, module_->RtxSendStatus());
}

}  // namespace webrtc
