// Copyright 2015 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 <memory>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "media/base/null_video_sink.h"
#include "media/base/test_helpers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::test::RunOnceClosure;
using testing::_;
using testing::DoAll;
using testing::Return;

namespace media {

using RenderingMode = VideoRendererSink::RenderCallback::RenderingMode;

class NullVideoSinkTest : public testing::Test,
                          public VideoRendererSink::RenderCallback {
 public:
  NullVideoSinkTest() {
    // Never use null TimeTicks since they have special connotations.
    tick_clock_.Advance(base::Microseconds(12345));
  }

  NullVideoSinkTest(const NullVideoSinkTest&) = delete;
  NullVideoSinkTest& operator=(const NullVideoSinkTest&) = delete;

  ~NullVideoSinkTest() override = default;

  std::unique_ptr<NullVideoSink> ConstructSink(bool clockless,
                                               base::TimeDelta interval) {
    std::unique_ptr<NullVideoSink> new_sink(
        new NullVideoSink(clockless, interval,
                          base::BindRepeating(&NullVideoSinkTest::FrameReceived,
                                              base::Unretained(this)),
                          task_environment_.GetMainThreadTaskRunner()));
    new_sink->set_tick_clock_for_testing(&tick_clock_);
    return new_sink;
  }

  scoped_refptr<VideoFrame> CreateFrame(base::TimeDelta timestamp) {
    const gfx::Size natural_size(8, 8);
    return VideoFrame::CreateFrame(PIXEL_FORMAT_I420, natural_size,
                                   gfx::Rect(natural_size), natural_size,
                                   timestamp);
  }
  base::TimeDelta GetPreferredRenderInterval() override {
    return viz::BeginFrameArgs::MinInterval();
  }

  // VideoRendererSink::RenderCallback implementation.
  MOCK_METHOD3(Render,
               scoped_refptr<VideoFrame>(base::TimeTicks,
                                         base::TimeTicks,
                                         RenderingMode));
  MOCK_METHOD0(OnFrameDropped, void());

  MOCK_METHOD1(FrameReceived, void(scoped_refptr<VideoFrame>));

 protected:
  base::test::SingleThreadTaskEnvironment task_environment_;
  base::SimpleTestTickClock tick_clock_;
};

TEST_F(NullVideoSinkTest, BasicFunctionality) {
  const base::TimeDelta kInterval = base::Milliseconds(25);

  std::unique_ptr<NullVideoSink> sink = ConstructSink(false, kInterval);
  scoped_refptr<VideoFrame> test_frame = CreateFrame(base::TimeDelta());

  {
    SCOPED_TRACE("Waiting for sink startup.");
    sink->Start(this);
    const base::TimeTicks current_time = tick_clock_.NowTicks();
    const base::TimeTicks current_interval_end = current_time + kInterval;
    EXPECT_CALL(*this, Render(current_time, current_interval_end,
                              RenderingMode::kNormal))
        .WillOnce(Return(test_frame));
    WaitableMessageLoopEvent event;
    EXPECT_CALL(*this, FrameReceived(test_frame))
        .WillOnce(RunOnceClosure(event.GetClosure()));
    event.RunAndWait();
  }

  // Verify that toggling background rendering mode issues the right bit to
  // each Render() call.
  sink->set_background_render(true);

  // A second call returning the same frame should not result in a new call to
  // FrameReceived().
  {
    SCOPED_TRACE("Waiting for second render call.");
    WaitableMessageLoopEvent event;
    scoped_refptr<VideoFrame> test_frame_2 = CreateFrame(kInterval);
    EXPECT_CALL(*this, Render(_, _, RenderingMode::kBackground))
        .WillOnce(Return(test_frame))
        .WillOnce(Return(test_frame_2));
    EXPECT_CALL(*this, FrameReceived(test_frame)).Times(0);
    EXPECT_CALL(*this, FrameReceived(test_frame_2))
        .WillOnce(RunOnceClosure(event.GetClosure()));
    event.RunAndWait();
  }

  {
    SCOPED_TRACE("Waiting for stop event.");
    WaitableMessageLoopEvent event;
    sink->set_stop_cb(event.GetClosure());
    sink->Stop();
    event.RunAndWait();
  }

  // The sink shouldn't have to be started to use the paint method.
  EXPECT_CALL(*this, FrameReceived(test_frame));
  sink->PaintSingleFrame(test_frame, false);
}

TEST_F(NullVideoSinkTest, ClocklessFunctionality) {
  // Construct the sink with a huge interval, it should still complete quickly.
  const base::TimeDelta interval = base::Seconds(10);
  std::unique_ptr<NullVideoSink> sink = ConstructSink(true, interval);

  scoped_refptr<VideoFrame> test_frame = CreateFrame(base::TimeDelta());
  scoped_refptr<VideoFrame> test_frame_2 = CreateFrame(interval);
  sink->Start(this);

  EXPECT_CALL(*this, FrameReceived(test_frame)).Times(1);
  EXPECT_CALL(*this, FrameReceived(test_frame_2)).Times(1);

  const int kTestRuns = 6;
  const base::TimeTicks now = base::TimeTicks::Now();
  const base::TimeTicks current_time = tick_clock_.NowTicks();

  SCOPED_TRACE("Waiting for multiple render callbacks");
  WaitableMessageLoopEvent event;
  for (int i = 0; i < kTestRuns; ++i) {
    if (i < kTestRuns - 1) {
      EXPECT_CALL(*this, Render(current_time + i * interval,
                                current_time + (i + 1) * interval,
                                RenderingMode::kNormal))
          .WillOnce(Return(test_frame));
    } else {
      EXPECT_CALL(*this, Render(current_time + i * interval,
                                current_time + (i + 1) * interval,
                                RenderingMode::kNormal))
          .WillOnce(
              DoAll(RunOnceClosure(event.GetClosure()), Return(test_frame_2)));
    }
  }
  event.RunAndWait();
  ASSERT_LT(base::TimeTicks::Now() - now, kTestRuns * interval);
  sink->Stop();
}

}  // namespace media
