// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/cast/receiver/frame_receiver.h"

#include <deque>
#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/base/fake_single_thread_task_runner.h"
#include "media/cast/cast_environment.h"
#include "media/cast/logging/simple_event_subscriber.h"
#include "media/cast/net/cast_transport_impl.h"
#include "media/cast/net/mock_cast_transport.h"
#include "media/cast/net/rtcp/rtcp_utility.h"
#include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
#include "media/cast/test/utility/default_config.h"
#include "starboard/types.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::_;

namespace cobalt {
namespace media {
namespace cast {

namespace {

const int kPacketSize = 1500;
const int kPlayoutDelayMillis = 100;

FrameId GetFirstTestFrameId() { return FrameId::first() + 1234; }

class FakeFrameClient {
 public:
  FakeFrameClient() : num_called_(0) {}
  virtual ~FakeFrameClient() {}

  void AddExpectedResult(FrameId expected_frame_id,
                         const base::TimeTicks& expected_playout_time) {
    expected_results_.push_back(
        std::make_pair(expected_frame_id, expected_playout_time));
  }

  void DeliverEncodedFrame(std::unique_ptr<EncodedFrame> frame) {
    SCOPED_TRACE(::testing::Message() << "num_called_ is " << num_called_);
    ASSERT_TRUE(frame)
        << "If at shutdown: There were unsatisfied requests enqueued.";
    ASSERT_FALSE(expected_results_.empty());
    EXPECT_EQ(expected_results_.front().first, frame->frame_id);
    EXPECT_EQ(expected_results_.front().second, frame->reference_time);
    expected_results_.pop_front();
    ++num_called_;
  }

  int number_times_called() const { return num_called_; }

 private:
  std::deque<std::pair<FrameId, base::TimeTicks>> expected_results_;
  int num_called_;

  DISALLOW_COPY_AND_ASSIGN(FakeFrameClient);
};
}  // namespace

class FrameReceiverTest : public ::testing::Test {
 protected:
  FrameReceiverTest() {
    testing_clock_ = new base::SimpleTestTickClock();
    testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
    start_time_ = testing_clock_->NowTicks();
    task_runner_ = new FakeSingleThreadTaskRunner(testing_clock_);

    cast_environment_ =
        new CastEnvironment(std::unique_ptr<base::TickClock>(testing_clock_),
                            task_runner_, task_runner_, task_runner_);
  }

  ~FrameReceiverTest() override {}

  void SetUp() final {
    payload_.assign(kPacketSize, 0);

    // Always start with a key frame.
    rtp_header_.is_key_frame = true;
    rtp_header_.frame_id = GetFirstTestFrameId();
    rtp_header_.packet_id = 0;
    rtp_header_.max_packet_id = 0;
    rtp_header_.reference_frame_id = rtp_header_.frame_id;
    rtp_header_.rtp_timestamp = RtpTimeTicks();
  }

  void CreateFrameReceiverOfAudio() {
    config_ = GetDefaultAudioReceiverConfig();
    config_.rtp_max_delay_ms = kPlayoutDelayMillis;

    receiver_.reset(new FrameReceiver(cast_environment_, config_, AUDIO_EVENT,
                                      &mock_transport_));
  }

  void CreateFrameReceiverOfVideo() {
    config_ = GetDefaultVideoReceiverConfig();
    config_.rtp_max_delay_ms = kPlayoutDelayMillis;
    // Note: Frame rate must divide 1000 without remainder so the test code
    // doesn't have to account for rounding errors.
    config_.target_frame_rate = 25;

    receiver_.reset(new FrameReceiver(cast_environment_, config_, VIDEO_EVENT,
                                      &mock_transport_));
  }

  void FeedOneFrameIntoReceiver() {
    // Note: For testing purposes, a frame consists of only a single packet.
    receiver_->ProcessParsedPacket(rtp_header_, &payload_[0], payload_.size());
  }

  void FeedLipSyncInfoIntoReceiver() {
    const base::TimeTicks now = testing_clock_->NowTicks();
    const RtpTimeTicks rtp_timestamp =
        RtpTimeTicks::FromTimeDelta(now - start_time_, config_.rtp_timebase);
    CHECK_LE(RtpTimeTicks(), rtp_timestamp);
    uint32_t ntp_seconds;
    uint32_t ntp_fraction;
    ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction);
    TestRtcpPacketBuilder rtcp_packet;
    rtcp_packet.AddSrWithNtp(config_.sender_ssrc, ntp_seconds, ntp_fraction,
                             rtp_timestamp.lower_32_bits());
    ASSERT_TRUE(receiver_->ProcessPacket(rtcp_packet.GetPacket()));
  }

  FrameReceiverConfig config_;
  std::vector<uint8_t> payload_;
  RtpCastHeader rtp_header_;
  base::SimpleTestTickClock* testing_clock_;  // Owned by CastEnvironment.
  base::TimeTicks start_time_;
  MockCastTransport mock_transport_;
  scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;
  scoped_refptr<CastEnvironment> cast_environment_;
  FakeFrameClient frame_client_;

  // Important for the FrameReceiver to be declared last, since its dependencies
  // must remain alive until after its destruction.
  std::unique_ptr<FrameReceiver> receiver_;

 private:
  DISALLOW_COPY_AND_ASSIGN(FrameReceiverTest);
};

TEST_F(FrameReceiverTest, RejectsUnparsablePackets) {
  EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
      .WillRepeatedly(testing::Return());

  CreateFrameReceiverOfVideo();

  SimpleEventSubscriber event_subscriber;
  cast_environment_->logger()->Subscribe(&event_subscriber);

  const bool success = receiver_->ProcessPacket(
      std::unique_ptr<Packet>(new Packet(kPacketSize, 0xff)));
  EXPECT_FALSE(success);

  // Confirm no log events.
  std::vector<FrameEvent> frame_events;
  event_subscriber.GetFrameEventsAndReset(&frame_events);
  EXPECT_TRUE(frame_events.empty());
  cast_environment_->logger()->Unsubscribe(&event_subscriber);
}

TEST_F(FrameReceiverTest, ReceivesOneFrame) {
  EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
      .WillRepeatedly(testing::Return());

  CreateFrameReceiverOfAudio();

  SimpleEventSubscriber event_subscriber;
  cast_environment_->logger()->Subscribe(&event_subscriber);

  EXPECT_CALL(mock_transport_, InitializeRtpReceiverRtcpBuilder(_, _))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddCastFeedback(_, _))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddPli(_)).WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddRtcpEvents(_))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver())
      .WillRepeatedly(testing::Return());

  FeedLipSyncInfoIntoReceiver();
  task_runner_->RunTasks();

  // Enqueue a request for a frame.
  receiver_->RequestEncodedFrame(base::Bind(
      &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_)));

  // The request should not be satisfied since no packets have been received.
  task_runner_->RunTasks();
  EXPECT_EQ(0, frame_client_.number_times_called());

  // Deliver one frame to the receiver and expect to get one frame back.
  const base::TimeDelta target_playout_delay =
      base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis);
  frame_client_.AddExpectedResult(
      GetFirstTestFrameId(), testing_clock_->NowTicks() + target_playout_delay);
  FeedOneFrameIntoReceiver();
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Was the frame logged?
  std::vector<FrameEvent> frame_events;
  event_subscriber.GetFrameEventsAndReset(&frame_events);
  ASSERT_TRUE(!frame_events.empty());
  EXPECT_EQ(FRAME_ACK_SENT, frame_events.begin()->type);
  EXPECT_EQ(AUDIO_EVENT, frame_events.begin()->media_type);
  EXPECT_EQ(rtp_header_.frame_id, frame_events.begin()->frame_id);
  EXPECT_EQ(rtp_header_.rtp_timestamp, frame_events.begin()->rtp_timestamp);
  cast_environment_->logger()->Unsubscribe(&event_subscriber);
}

TEST_F(FrameReceiverTest, ReceivesFramesSkippingWhenAppropriate) {
  EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
      .WillRepeatedly(testing::Return());

  CreateFrameReceiverOfAudio();

  SimpleEventSubscriber event_subscriber;
  cast_environment_->logger()->Subscribe(&event_subscriber);

  EXPECT_CALL(mock_transport_, InitializeRtpReceiverRtcpBuilder(_, _))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddCastFeedback(_, _))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddPli(_)).WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddRtcpEvents(_))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver())
      .WillRepeatedly(testing::Return());

  const base::TimeDelta time_advance_per_frame =
      base::TimeDelta::FromSeconds(1) / config_.target_frame_rate;
  const RtpTimeDelta rtp_advance_per_frame =
      RtpTimeDelta::FromTimeDelta(time_advance_per_frame, config_.rtp_timebase);

  // Feed and process lip sync in receiver.
  FeedLipSyncInfoIntoReceiver();
  task_runner_->RunTasks();
  const base::TimeTicks first_frame_capture_time = testing_clock_->NowTicks();

  // Enqueue a request for a frame.
  const ReceiveEncodedFrameCallback frame_encoded_callback = base::Bind(
      &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_));
  receiver_->RequestEncodedFrame(frame_encoded_callback);
  task_runner_->RunTasks();
  EXPECT_EQ(0, frame_client_.number_times_called());

  // Receive one frame and expect to see the first request satisfied.
  const base::TimeDelta target_playout_delay =
      base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis);
  frame_client_.AddExpectedResult(
      GetFirstTestFrameId(), first_frame_capture_time + target_playout_delay);
  rtp_header_.rtp_timestamp = RtpTimeTicks();
  FeedOneFrameIntoReceiver();  // Frame 1
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Enqueue a second request for a frame, but it should not be fulfilled yet.
  receiver_->RequestEncodedFrame(frame_encoded_callback);
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Receive one frame out-of-order: Make sure that we are not continuous and
  // that the RTP timestamp represents a time in the future.
  rtp_header_.frame_id = GetFirstTestFrameId() + 2;  // "Frame 3"
  rtp_header_.reference_frame_id = rtp_header_.frame_id;
  rtp_header_.rtp_timestamp += rtp_advance_per_frame * 2;
  frame_client_.AddExpectedResult(rtp_header_.frame_id,
                                  first_frame_capture_time +
                                      2 * time_advance_per_frame +
                                      target_playout_delay);
  FeedOneFrameIntoReceiver();  // Frame 3

  // Frame 2 should not come out at this point in time.
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Enqueue a third request for a frame.
  receiver_->RequestEncodedFrame(frame_encoded_callback);
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Now, advance time forward such that the receiver is convinced it should
  // skip Frame 2.  Frame 3 is emitted (to satisfy the second request) because a
  // decision was made to skip over the no-show Frame 2.
  testing_clock_->Advance(2 * time_advance_per_frame + target_playout_delay);
  task_runner_->RunTasks();
  EXPECT_EQ(2, frame_client_.number_times_called());

  // Receive Frame 4 and expect it to fulfill the third request immediately.
  rtp_header_.frame_id = GetFirstTestFrameId() + 3;  // "Frame 4"
  rtp_header_.reference_frame_id = rtp_header_.frame_id;
  rtp_header_.rtp_timestamp += rtp_advance_per_frame;
  frame_client_.AddExpectedResult(rtp_header_.frame_id,
                                  first_frame_capture_time +
                                      3 * time_advance_per_frame +
                                      target_playout_delay);
  FeedOneFrameIntoReceiver();  // Frame 4
  task_runner_->RunTasks();
  EXPECT_EQ(3, frame_client_.number_times_called());

  // Move forward to the playout time of an unreceived Frame 5.  Expect no
  // additional frames were emitted.
  testing_clock_->Advance(3 * time_advance_per_frame);
  task_runner_->RunTasks();
  EXPECT_EQ(3, frame_client_.number_times_called());

  // Were only non-skipped frames logged?
  std::vector<FrameEvent> frame_events;
  event_subscriber.GetFrameEventsAndReset(&frame_events);
  ASSERT_TRUE(!frame_events.empty());
  for (size_t i = 0; i < frame_events.size(); ++i) {
    EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type);
    EXPECT_EQ(AUDIO_EVENT, frame_events[i].media_type);
    EXPECT_LE(GetFirstTestFrameId(), frame_events[i].frame_id);
    EXPECT_GE(GetFirstTestFrameId() + 4, frame_events[i].frame_id);
    const int frame_offset = frame_events[i].frame_id - GetFirstTestFrameId();
    EXPECT_NE(frame_offset, 1);  // Frame 2 never received.
    EXPECT_EQ(RtpTimeTicks() + (rtp_advance_per_frame * frame_offset),
              frame_events[i].rtp_timestamp);
  }
  cast_environment_->logger()->Unsubscribe(&event_subscriber);
}

TEST_F(FrameReceiverTest, ReceivesFramesRefusingToSkipAny) {
  EXPECT_CALL(mock_transport_, AddValidRtpReceiver(_, _))
      .WillRepeatedly(testing::Return());

  CreateFrameReceiverOfVideo();

  SimpleEventSubscriber event_subscriber;
  cast_environment_->logger()->Subscribe(&event_subscriber);

  EXPECT_CALL(mock_transport_, InitializeRtpReceiverRtcpBuilder(_, _))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddCastFeedback(_, _))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddPli(_)).WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, AddRtcpEvents(_))
      .WillRepeatedly(testing::Return());
  EXPECT_CALL(mock_transport_, SendRtcpFromRtpReceiver())
      .WillRepeatedly(testing::Return());

  const base::TimeDelta time_advance_per_frame =
      base::TimeDelta::FromSeconds(1) / config_.target_frame_rate;
  const RtpTimeDelta rtp_advance_per_frame =
      RtpTimeDelta::FromTimeDelta(time_advance_per_frame, config_.rtp_timebase);

  // Feed and process lip sync in receiver.
  FeedLipSyncInfoIntoReceiver();
  task_runner_->RunTasks();
  const base::TimeTicks first_frame_capture_time = testing_clock_->NowTicks();

  // Enqueue a request for a frame.
  const ReceiveEncodedFrameCallback frame_encoded_callback = base::Bind(
      &FakeFrameClient::DeliverEncodedFrame, base::Unretained(&frame_client_));
  receiver_->RequestEncodedFrame(frame_encoded_callback);
  task_runner_->RunTasks();
  EXPECT_EQ(0, frame_client_.number_times_called());

  // Receive one frame and expect to see the first request satisfied.
  const base::TimeDelta target_playout_delay =
      base::TimeDelta::FromMilliseconds(kPlayoutDelayMillis);
  frame_client_.AddExpectedResult(
      GetFirstTestFrameId(), first_frame_capture_time + target_playout_delay);
  rtp_header_.rtp_timestamp = RtpTimeTicks();
  FeedOneFrameIntoReceiver();  // Frame 1
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Enqueue a second request for a frame, but it should not be fulfilled yet.
  receiver_->RequestEncodedFrame(frame_encoded_callback);
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Receive one frame out-of-order: Make sure that we are not continuous and
  // that the RTP timestamp represents a time in the future.
  rtp_header_.is_key_frame = false;
  rtp_header_.frame_id = GetFirstTestFrameId() + 2;            // "Frame 3"
  rtp_header_.reference_frame_id = GetFirstTestFrameId() + 1;  // "Frame 2"
  rtp_header_.rtp_timestamp += rtp_advance_per_frame * 2;
  FeedOneFrameIntoReceiver();  // Frame 3

  // Frame 2 should not come out at this point in time.
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Enqueue a third request for a frame.
  receiver_->RequestEncodedFrame(frame_encoded_callback);
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Now, advance time forward such that Frame 2 is now too late for playback.
  // Regardless, the receiver must NOT emit Frame 3 yet because it is not
  // allowed to skip frames when dependencies are not satisfied.  In other
  // words, Frame 3 is not decodable without Frame 2.
  testing_clock_->Advance(2 * time_advance_per_frame + target_playout_delay);
  task_runner_->RunTasks();
  EXPECT_EQ(1, frame_client_.number_times_called());

  // Now receive Frame 2 and expect both the second and third requests to be
  // fulfilled immediately.
  frame_client_.AddExpectedResult(GetFirstTestFrameId() + 1,  // "Frame 2"
                                  first_frame_capture_time +
                                      1 * time_advance_per_frame +
                                      target_playout_delay);
  frame_client_.AddExpectedResult(GetFirstTestFrameId() + 2,  // "Frame 3"
                                  first_frame_capture_time +
                                      2 * time_advance_per_frame +
                                      target_playout_delay);
  --rtp_header_.frame_id;            // "Frame 2"
  --rtp_header_.reference_frame_id;  // "Frame 1"
  rtp_header_.rtp_timestamp -= rtp_advance_per_frame;
  FeedOneFrameIntoReceiver();  // Frame 2
  task_runner_->RunTasks();
  EXPECT_EQ(3, frame_client_.number_times_called());

  // Move forward to the playout time of an unreceived Frame 5.  Expect no
  // additional frames were emitted.
  testing_clock_->Advance(3 * time_advance_per_frame);
  task_runner_->RunTasks();
  EXPECT_EQ(3, frame_client_.number_times_called());

  // Sanity-check logging results.
  std::vector<FrameEvent> frame_events;
  event_subscriber.GetFrameEventsAndReset(&frame_events);
  ASSERT_TRUE(!frame_events.empty());
  for (size_t i = 0; i < frame_events.size(); ++i) {
    EXPECT_EQ(FRAME_ACK_SENT, frame_events[i].type);
    EXPECT_EQ(VIDEO_EVENT, frame_events[i].media_type);
    EXPECT_LE(GetFirstTestFrameId(), frame_events[i].frame_id);
    EXPECT_GE(GetFirstTestFrameId() + 3, frame_events[i].frame_id);
    const int frame_offset = frame_events[i].frame_id - GetFirstTestFrameId();
    EXPECT_EQ(RtpTimeTicks() + (rtp_advance_per_frame * frame_offset),
              frame_events[i].rtp_timestamp);
  }
  cast_environment_->logger()->Unsubscribe(&event_subscriber);
}

}  // namespace cast
}  // namespace media
}  // namespace cobalt
