// 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 <stddef.h>
#include <stdint.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 "testing/gmock/include/gmock/gmock.h"

using ::testing::_;

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
