// 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/net/rtcp/receiver_rtcp_event_subscriber.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <utility>

#include "base/memory/ref_counted.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/tick_clock.h"
#include "media/base/fake_single_thread_task_runner.h"
#include "media/cast/cast_environment.h"
#include "media/cast/logging/logging_defines.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {
namespace cast {

namespace {

const size_t kMaxEventEntries = 10u;
const int64_t kDelayMs = 20L;

}  // namespace

class ReceiverRtcpEventSubscriberTest : public ::testing::Test {
 protected:
  ReceiverRtcpEventSubscriberTest()
      : task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)),
        cast_environment_(new CastEnvironment(&testing_clock_,
                                              task_runner_,
                                              task_runner_,
                                              task_runner_)) {}

  ~ReceiverRtcpEventSubscriberTest() override = default;

  void TearDown() final {
    if (event_subscriber_) {
      cast_environment_->logger()->Unsubscribe(event_subscriber_.get());
      event_subscriber_.reset();
    }
  }

  void Init(EventMediaType type) {
    event_subscriber_ =
        std::make_unique<ReceiverRtcpEventSubscriber>(kMaxEventEntries, type);
    cast_environment_->logger()->Subscribe(event_subscriber_.get());
  }

  void InsertEvents() {
    // Video events
    std::unique_ptr<FrameEvent> playout_event(new FrameEvent());
    playout_event->timestamp = testing_clock_.NowTicks();
    playout_event->type = FRAME_PLAYOUT;
    playout_event->media_type = VIDEO_EVENT;
    playout_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(100));
    playout_event->frame_id = FrameId::first() + 2;
    playout_event->delay_delta = base::Milliseconds(kDelayMs);
    cast_environment_->logger()->DispatchFrameEvent(std::move(playout_event));

    std::unique_ptr<FrameEvent> decode_event(new FrameEvent());
    decode_event->timestamp = testing_clock_.NowTicks();
    decode_event->type = FRAME_DECODED;
    decode_event->media_type = VIDEO_EVENT;
    decode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(200));
    decode_event->frame_id = FrameId::first() + 1;
    cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event));

    std::unique_ptr<PacketEvent> receive_event(new PacketEvent());
    receive_event->timestamp = testing_clock_.NowTicks();
    receive_event->type = PACKET_RECEIVED;
    receive_event->media_type = VIDEO_EVENT;
    receive_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(200));
    receive_event->frame_id = FrameId::first() + 2;
    receive_event->packet_id = 1u;
    receive_event->max_packet_id = 10u;
    receive_event->size = 1024u;
    cast_environment_->logger()->DispatchPacketEvent(std::move(receive_event));

    // Audio events
    playout_event = std::make_unique<FrameEvent>();
    playout_event->timestamp = testing_clock_.NowTicks();
    playout_event->type = FRAME_PLAYOUT;
    playout_event->media_type = AUDIO_EVENT;
    playout_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(300));
    playout_event->frame_id = FrameId::first() + 4;
    playout_event->delay_delta = base::Milliseconds(kDelayMs);
    cast_environment_->logger()->DispatchFrameEvent(std::move(playout_event));

    decode_event = std::make_unique<FrameEvent>();
    decode_event->timestamp = testing_clock_.NowTicks();
    decode_event->type = FRAME_DECODED;
    decode_event->media_type = AUDIO_EVENT;
    decode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(400));
    decode_event->frame_id = FrameId::first() + 3;
    cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event));

    receive_event = std::make_unique<PacketEvent>();
    receive_event->timestamp = testing_clock_.NowTicks();
    receive_event->type = PACKET_RECEIVED;
    receive_event->media_type = AUDIO_EVENT;
    receive_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(400));
    receive_event->frame_id = FrameId::first() + 5;
    receive_event->packet_id = 1u;
    receive_event->max_packet_id = 10u;
    receive_event->size = 128u;
    cast_environment_->logger()->DispatchPacketEvent(std::move(receive_event));

    // Unrelated events
    std::unique_ptr<FrameEvent> encode_event(new FrameEvent());
    encode_event->timestamp = testing_clock_.NowTicks();
    encode_event->type = FRAME_ENCODED;
    encode_event->media_type = VIDEO_EVENT;
    encode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(100));
    encode_event->frame_id = FrameId::first() + 1;
    cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event));

    encode_event = std::make_unique<FrameEvent>();
    encode_event->timestamp = testing_clock_.NowTicks();
    encode_event->type = FRAME_ENCODED;
    encode_event->media_type = AUDIO_EVENT;
    encode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(100));
    encode_event->frame_id = FrameId::first() + 1;
    cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event));
  }

  base::SimpleTestTickClock testing_clock_;
  scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;
  scoped_refptr<CastEnvironment> cast_environment_;
  std::unique_ptr<ReceiverRtcpEventSubscriber> event_subscriber_;
};

TEST_F(ReceiverRtcpEventSubscriberTest, LogVideoEvents) {
  Init(VIDEO_EVENT);

  InsertEvents();
  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
  event_subscriber_->GetRtcpEventsWithRedundancy(&rtcp_events);
  EXPECT_EQ(3u, rtcp_events.size());
}

TEST_F(ReceiverRtcpEventSubscriberTest, LogAudioEvents) {
  Init(AUDIO_EVENT);

  InsertEvents();
  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
  event_subscriber_->GetRtcpEventsWithRedundancy(&rtcp_events);
  EXPECT_EQ(3u, rtcp_events.size());
}

TEST_F(ReceiverRtcpEventSubscriberTest, DropEventsWhenSizeExceeded) {
  Init(VIDEO_EVENT);

  for (int i = 1; i <= 10; ++i) {
    std::unique_ptr<FrameEvent> decode_event(new FrameEvent());
    decode_event->timestamp = testing_clock_.NowTicks();
    decode_event->type = FRAME_DECODED;
    decode_event->media_type = VIDEO_EVENT;
    decode_event->rtp_timestamp =
        RtpTimeTicks().Expand(static_cast<unsigned int>(i * 10));
    decode_event->frame_id = FrameId::first() + i;
    cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event));
  }

  ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events;
  event_subscriber_->GetRtcpEventsWithRedundancy(&rtcp_events);
  EXPECT_EQ(10u, rtcp_events.size());
}

}  // namespace cast
}  // namespace media
