/*
 *  Copyright (c) 2015 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 <limits>
#include <memory>
#include <vector>

#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"

#include "webrtc/base/checks.h"
#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "webrtc/system_wrappers/include/clock.h"

using ::testing::_;
using ::testing::Invoke;

namespace webrtc {
namespace test {

class TransportFeedbackAdapterTest : public ::testing::Test {
 public:
  TransportFeedbackAdapterTest()
      : clock_(0),
        bitrate_estimator_(nullptr),
        bitrate_controller_(this),
        receiver_estimated_bitrate_(0) {}

  virtual ~TransportFeedbackAdapterTest() {}

  virtual void SetUp() {
    adapter_.reset(new TransportFeedbackAdapter(&clock_));

    bitrate_estimator_ = new MockRemoteBitrateEstimator();
    adapter_->SetBitrateEstimator(bitrate_estimator_);
  }

  virtual void TearDown() {
    adapter_.reset();
  }

 protected:
  // Proxy class used since TransportFeedbackAdapter will own the instance
  // passed at construction.
  class MockBitrateControllerAdapter : public MockBitrateController {
   public:
    explicit MockBitrateControllerAdapter(TransportFeedbackAdapterTest* owner)
        : MockBitrateController(), owner_(owner) {}

    ~MockBitrateControllerAdapter() override {}

    void OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
                                 uint32_t bitrate_bps) override {
      owner_->receiver_estimated_bitrate_ = bitrate_bps;
    }

    TransportFeedbackAdapterTest* const owner_;
  };

  void OnReceivedEstimatedBitrate(uint32_t bitrate) {}

  void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
                                    int64_t rtt,
                                    int64_t now_ms) {}

  void ComparePacketVectors(const std::vector<PacketInfo>& truth,
                            const std::vector<PacketInfo>& input) {
    ASSERT_EQ(truth.size(), input.size());
    size_t len = truth.size();
    // truth contains the input data for the test, and input is what will be
    // sent to the bandwidth estimator. truth.arrival_tims_ms is used to
    // populate the transport feedback messages. As these times may be changed
    // (because of resolution limits in the packets, and because of the time
    // base adjustment performed by the TransportFeedbackAdapter at the first
    // packet, the truth[x].arrival_time and input[x].arrival_time may not be
    // equal. However, the difference must be the same for all x.
    int64_t arrival_time_delta =
        truth[0].arrival_time_ms - input[0].arrival_time_ms;
    for (size_t i = 0; i < len; ++i) {
      EXPECT_EQ(truth[i].arrival_time_ms,
                input[i].arrival_time_ms + arrival_time_delta);
      EXPECT_EQ(truth[i].send_time_ms, input[i].send_time_ms);
      EXPECT_EQ(truth[i].sequence_number, input[i].sequence_number);
      EXPECT_EQ(truth[i].payload_size, input[i].payload_size);
      EXPECT_EQ(truth[i].probe_cluster_id, input[i].probe_cluster_id);
    }
  }

  // Utility method, to reset arrival_time_ms before adding send time.
  void OnSentPacket(PacketInfo info) {
    info.arrival_time_ms = 0;
    adapter_->AddPacket(info.sequence_number, info.payload_size,
                        info.probe_cluster_id);
    adapter_->OnSentPacket(info.sequence_number, info.send_time_ms);
  }

  SimulatedClock clock_;
  MockRemoteBitrateEstimator* bitrate_estimator_;
  MockBitrateControllerAdapter bitrate_controller_;
  std::unique_ptr<TransportFeedbackAdapter> adapter_;

  uint32_t receiver_estimated_bitrate_;
};

TEST_F(TransportFeedbackAdapterTest, AdaptsFeedbackAndPopulatesSendTimes) {
  std::vector<PacketInfo> packets;
  packets.push_back(PacketInfo(100, 200, 0, 1500, 0));
  packets.push_back(PacketInfo(110, 210, 1, 1500, 0));
  packets.push_back(PacketInfo(120, 220, 2, 1500, 0));
  packets.push_back(PacketInfo(130, 230, 3, 1500, 1));
  packets.push_back(PacketInfo(140, 240, 4, 1500, 1));

  for (const PacketInfo& packet : packets)
    OnSentPacket(packet);

  rtcp::TransportFeedback feedback;
  feedback.SetBase(packets[0].sequence_number,
                   packets[0].arrival_time_ms * 1000);

  for (const PacketInfo& packet : packets) {
    EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
                                           packet.arrival_time_ms * 1000));
  }

  feedback.Build();

  EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
      .Times(1)
      .WillOnce(Invoke(
          [packets, this](const std::vector<PacketInfo>& feedback_vector) {
            ComparePacketVectors(packets, feedback_vector);
          }));
  adapter_->OnTransportFeedback(feedback);
}

TEST_F(TransportFeedbackAdapterTest, HandlesDroppedPackets) {
  std::vector<PacketInfo> packets;
  packets.push_back(PacketInfo(100, 200, 0, 1500, 1));
  packets.push_back(PacketInfo(110, 210, 1, 1500, 2));
  packets.push_back(PacketInfo(120, 220, 2, 1500, 3));
  packets.push_back(PacketInfo(130, 230, 3, 1500, 4));
  packets.push_back(PacketInfo(140, 240, 4, 1500, 5));

  const uint16_t kSendSideDropBefore = 1;
  const uint16_t kReceiveSideDropAfter = 3;

  for (const PacketInfo& packet : packets) {
    if (packet.sequence_number >= kSendSideDropBefore)
      OnSentPacket(packet);
  }

  rtcp::TransportFeedback feedback;
  feedback.SetBase(packets[0].sequence_number,
                   packets[0].arrival_time_ms * 1000);

  for (const PacketInfo& packet : packets) {
    if (packet.sequence_number <= kReceiveSideDropAfter) {
      EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
                                             packet.arrival_time_ms * 1000));
    }
  }

  feedback.Build();

  std::vector<PacketInfo> expected_packets(
      packets.begin() + kSendSideDropBefore,
      packets.begin() + kReceiveSideDropAfter + 1);

  EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
      .Times(1)
      .WillOnce(Invoke([expected_packets,
                        this](const std::vector<PacketInfo>& feedback_vector) {
        ComparePacketVectors(expected_packets, feedback_vector);
      }));
  adapter_->OnTransportFeedback(feedback);
}

TEST_F(TransportFeedbackAdapterTest, SendTimeWrapsBothWays) {
  int64_t kHighArrivalTimeMs = rtcp::TransportFeedback::kDeltaScaleFactor *
                               static_cast<int64_t>(1 << 8) *
                               static_cast<int64_t>((1 << 23) - 1) / 1000;
  std::vector<PacketInfo> packets;
  packets.push_back(PacketInfo(kHighArrivalTimeMs - 64, 200, 0, 1500,
                               PacketInfo::kNotAProbe));
  packets.push_back(PacketInfo(kHighArrivalTimeMs + 64, 210, 1, 1500,
                               PacketInfo::kNotAProbe));
  packets.push_back(
      PacketInfo(kHighArrivalTimeMs, 220, 2, 1500, PacketInfo::kNotAProbe));

  for (const PacketInfo& packet : packets)
    OnSentPacket(packet);

  for (size_t i = 0; i < packets.size(); ++i) {
    std::unique_ptr<rtcp::TransportFeedback> feedback(
        new rtcp::TransportFeedback());
    feedback->SetBase(packets[i].sequence_number,
                      packets[i].arrival_time_ms * 1000);

    EXPECT_TRUE(feedback->AddReceivedPacket(packets[i].sequence_number,
                                            packets[i].arrival_time_ms * 1000));

    rtc::Buffer raw_packet = feedback->Build();
    feedback = rtcp::TransportFeedback::ParseFrom(raw_packet.data(),
                                                  raw_packet.size());

    std::vector<PacketInfo> expected_packets;
    expected_packets.push_back(packets[i]);

    EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
        .Times(1)
        .WillOnce(Invoke([expected_packets, this](
            const std::vector<PacketInfo>& feedback_vector) {
          ComparePacketVectors(expected_packets, feedback_vector);
        }));
    adapter_->OnTransportFeedback(*feedback.get());
  }
}

TEST_F(TransportFeedbackAdapterTest, HandlesReordering) {
  std::vector<PacketInfo> packets;
  packets.push_back(PacketInfo(120, 200, 0, 1500, 0));
  packets.push_back(PacketInfo(110, 210, 1, 1500, 0));
  packets.push_back(PacketInfo(100, 220, 2, 1500, 0));
  std::vector<PacketInfo> expected_packets;
  expected_packets.push_back(packets[2]);
  expected_packets.push_back(packets[1]);
  expected_packets.push_back(packets[0]);

  for (const PacketInfo& packet : packets)
    OnSentPacket(packet);

  rtcp::TransportFeedback feedback;
  feedback.SetBase(packets[0].sequence_number,
                   packets[0].arrival_time_ms * 1000);

  for (const PacketInfo& packet : packets) {
    EXPECT_TRUE(feedback.AddReceivedPacket(packet.sequence_number,
                                           packet.arrival_time_ms * 1000));
  }

  feedback.Build();

  EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
      .Times(1)
      .WillOnce(Invoke([expected_packets,
                        this](const std::vector<PacketInfo>& feedback_vector) {
        ComparePacketVectors(expected_packets, feedback_vector);
      }));
  adapter_->OnTransportFeedback(feedback);
}

TEST_F(TransportFeedbackAdapterTest, TimestampDeltas) {
  std::vector<PacketInfo> sent_packets;
  const int64_t kSmallDeltaUs =
      rtcp::TransportFeedback::kDeltaScaleFactor * ((1 << 8) - 1);
  const int64_t kLargePositiveDeltaUs =
      rtcp::TransportFeedback::kDeltaScaleFactor *
      std::numeric_limits<int16_t>::max();
  const int64_t kLargeNegativeDeltaUs =
      rtcp::TransportFeedback::kDeltaScaleFactor *
      std::numeric_limits<int16_t>::min();

  PacketInfo info(100, 200, 0, 1500, true, PacketInfo::kNotAProbe);
  sent_packets.push_back(info);

  info.send_time_ms += kSmallDeltaUs / 1000;
  info.arrival_time_ms += kSmallDeltaUs / 1000;
  ++info.sequence_number;
  sent_packets.push_back(info);

  info.send_time_ms += kLargePositiveDeltaUs / 1000;
  info.arrival_time_ms += kLargePositiveDeltaUs / 1000;
  ++info.sequence_number;
  sent_packets.push_back(info);

  info.send_time_ms += kLargeNegativeDeltaUs / 1000;
  info.arrival_time_ms += kLargeNegativeDeltaUs / 1000;
  ++info.sequence_number;
  sent_packets.push_back(info);

  // Too large, delta - will need two feedback messages.
  info.send_time_ms += (kLargePositiveDeltaUs + 1000) / 1000;
  info.arrival_time_ms += (kLargePositiveDeltaUs + 1000) / 1000;
  ++info.sequence_number;

  // Expected to be ordered on arrival time when the feedback message has been
  // parsed.
  std::vector<PacketInfo> expected_packets;
  expected_packets.push_back(sent_packets[0]);
  expected_packets.push_back(sent_packets[3]);
  expected_packets.push_back(sent_packets[1]);
  expected_packets.push_back(sent_packets[2]);

  // Packets will be added to send history.
  for (const PacketInfo& packet : sent_packets)
    OnSentPacket(packet);
  OnSentPacket(info);

  // Create expected feedback and send into adapter.
  std::unique_ptr<rtcp::TransportFeedback> feedback(
      new rtcp::TransportFeedback());
  feedback->SetBase(sent_packets[0].sequence_number,
                    sent_packets[0].arrival_time_ms * 1000);

  for (const PacketInfo& packet : sent_packets) {
    EXPECT_TRUE(feedback->AddReceivedPacket(packet.sequence_number,
                                            packet.arrival_time_ms * 1000));
  }
  EXPECT_FALSE(feedback->AddReceivedPacket(info.sequence_number,
                                           info.arrival_time_ms * 1000));

  rtc::Buffer raw_packet = feedback->Build();
  feedback =
      rtcp::TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size());

  std::vector<PacketInfo> received_feedback;

  EXPECT_TRUE(feedback.get() != nullptr);
  EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
      .Times(1)
      .WillOnce(Invoke([expected_packets, &received_feedback](
          const std::vector<PacketInfo>& feedback_vector) {
        EXPECT_EQ(expected_packets.size(), feedback_vector.size());
        received_feedback = feedback_vector;
      }));
  adapter_->OnTransportFeedback(*feedback.get());

  // Create a new feedback message and add the trailing item.
  feedback.reset(new rtcp::TransportFeedback());
  feedback->SetBase(info.sequence_number, info.arrival_time_ms * 1000);
  EXPECT_TRUE(feedback->AddReceivedPacket(info.sequence_number,
                                          info.arrival_time_ms * 1000));
  raw_packet = feedback->Build();
  feedback =
      rtcp::TransportFeedback::ParseFrom(raw_packet.data(), raw_packet.size());

  EXPECT_TRUE(feedback.get() != nullptr);
  EXPECT_CALL(*bitrate_estimator_, IncomingPacketFeedbackVector(_))
      .Times(1)
      .WillOnce(Invoke(
          [&received_feedback](const std::vector<PacketInfo>& feedback_vector) {
            EXPECT_EQ(1u, feedback_vector.size());
            received_feedback.push_back(feedback_vector[0]);
          }));
  adapter_->OnTransportFeedback(*feedback.get());

  expected_packets.push_back(info);

  ComparePacketVectors(expected_packets, received_feedback);
}

}  // namespace test
}  // namespace webrtc
