// 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/message_loop/message_loop.h"
#include "base/test/simple_test_tick_clock.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "media/base/gmock_callback_support.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 testing::_;
using testing::DoAll;
using testing::Return;

namespace media {

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

  std::unique_ptr<NullVideoSink> ConstructSink(bool clockless,
                                               base::TimeDelta interval) {
    std::unique_ptr<NullVideoSink> new_sink(new NullVideoSink(
        clockless, interval,
        base::Bind(&NullVideoSinkTest::FrameReceived, base::Unretained(this)),
        message_loop_.task_runner()));
    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,
                                         bool));
  MOCK_METHOD0(OnFrameDropped, void());

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

 protected:
  base::MessageLoop message_loop_;
  base::SimpleTestTickClock tick_clock_;

  DISALLOW_COPY_AND_ASSIGN(NullVideoSinkTest);
};

TEST_F(NullVideoSinkTest, BasicFunctionality) {
  const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(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, false))
        .WillOnce(Return(test_frame));
    WaitableMessageLoopEvent event;
    EXPECT_CALL(*this, FrameReceived(test_frame))
        .WillOnce(RunClosure(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(_, _, true))
        .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(RunClosure(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::TimeDelta::FromSeconds(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, false))
          .WillOnce(Return(test_frame));
    } else {
      EXPECT_CALL(*this, Render(current_time + i * interval,
                                current_time + (i + 1) * interval, false))
          .WillOnce(
              DoAll(RunClosure(event.GetClosure()), Return(test_frame_2)));
    }
  }
  event.RunAndWait();
  ASSERT_LT(base::TimeTicks::Now() - now, kTestRuns * interval);
  sink->Stop();
}

}  // namespace media
