// Copyright 2017 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 "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "media/capture/video/video_capture_device_info.h"
#include "services/service_manager/public/cpp/service_keepalive.h"
#include "services/video_capture/public/cpp/mock_producer.h"
#include "services/video_capture/public/cpp/mock_receiver.h"
#include "services/video_capture/shared_memory_virtual_device_mojo_adapter.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Invoke;
using testing::Mock;

namespace video_capture {

namespace {

const std::string kTestDeviceId = "/test/device";
const std::string kTestDeviceName = "Test Device";
const gfx::Size kTestFrameSize = {640 /* width */, 480 /* height */};
const media::VideoPixelFormat kTestPixelFormat =
    media::VideoPixelFormat::PIXEL_FORMAT_I420;

}  // anonymous namespace

class VirtualDeviceTest : public ::testing::Test {
 public:
  VirtualDeviceTest() : keepalive_(nullptr, base::nullopt) {}
  ~VirtualDeviceTest() override {}

  void SetUp() override {
    device_info_.descriptor.device_id = kTestDeviceId;
    device_info_.descriptor.set_display_name(kTestDeviceName);
    mojom::ProducerPtr producer_proxy;
    producer_ =
        std::make_unique<MockProducer>(mojo::MakeRequest(&producer_proxy));
    device_adapter_ = std::make_unique<SharedMemoryVirtualDeviceMojoAdapter>(
        keepalive_.CreateRef(), std::move(producer_proxy));
  }

  void OnFrameBufferReceived(bool valid_buffer_expected, int32_t buffer_id) {
    if (!valid_buffer_expected) {
      EXPECT_EQ(-1, buffer_id);
      return;
    }

    EXPECT_NE(-1, buffer_id);
    received_buffer_ids_.push_back(buffer_id);
  }

  void VerifyAndGetMaxFrameBuffers() {
    base::RunLoop wait_loop;
    EXPECT_CALL(*producer_, DoOnNewBuffer(_, _, _))
        .Times(SharedMemoryVirtualDeviceMojoAdapter::
                   max_buffer_pool_buffer_count())
        .WillRepeatedly(Invoke(
            [](int32_t buffer_id, media::mojom::VideoBufferHandlePtr* handle,
               mojom::Producer::OnNewBufferCallback& callback) {
              std::move(callback).Run();
            }));
    // Should receive valid buffer for up to the maximum buffer count.
    for (int i = 0;
         i <
         SharedMemoryVirtualDeviceMojoAdapter::max_buffer_pool_buffer_count();
         i++) {
      device_adapter_->RequestFrameBuffer(
          kTestFrameSize, kTestPixelFormat, nullptr,
          base::Bind(&VirtualDeviceTest::OnFrameBufferReceived,
                     base::Unretained(this), true /* valid_buffer_expected */));
    }

    // No more buffer available. Invalid buffer id should be returned.
    device_adapter_->RequestFrameBuffer(
        kTestFrameSize, kTestPixelFormat, nullptr,
        base::Bind(&VirtualDeviceTest::OnFrameBufferReceived,
                   base::Unretained(this), false /* valid_buffer_expected */));

    wait_loop.RunUntilIdle();
    Mock::VerifyAndClearExpectations(producer_.get());
    EXPECT_EQ(
        SharedMemoryVirtualDeviceMojoAdapter::max_buffer_pool_buffer_count(),
        static_cast<int>(received_buffer_ids_.size()));
  }

 protected:
  std::unique_ptr<SharedMemoryVirtualDeviceMojoAdapter> device_adapter_;
  // ID of buffers received and owned by the producer.
  std::vector<int> received_buffer_ids_;
  std::unique_ptr<MockProducer> producer_;

 private:
  base::MessageLoop loop_;
  service_manager::ServiceKeepalive keepalive_;
  media::VideoCaptureDeviceInfo device_info_;
};

TEST_F(VirtualDeviceTest, OnFrameReadyInBufferWithoutReceiver) {
  // Obtain maximum number of buffers.
  VerifyAndGetMaxFrameBuffers();

  base::RunLoop wait_loop;

  // Release one buffer back to the pool, no consumer hold since there is no
  // receiver.
  device_adapter_->OnFrameReadyInBuffer(received_buffer_ids_.at(0),
                                        media::mojom::VideoFrameInfo::New());

  // Verify there is a buffer available now, without creating a new
  // buffer.
  EXPECT_CALL(*producer_, DoOnNewBuffer(_, _, _)).Times(0);
  device_adapter_->RequestFrameBuffer(
      kTestFrameSize, kTestPixelFormat, nullptr,
      base::Bind(&VirtualDeviceTest::OnFrameBufferReceived,
                 base::Unretained(this), true /* valid_buffer_expected */));

  wait_loop.RunUntilIdle();
}

TEST_F(VirtualDeviceTest, OnFrameReadyInBufferWithReceiver) {
  // Obtain maximum number of buffers for the producer.
  VerifyAndGetMaxFrameBuffers();

  // Release all buffers back to consumer, then back to the pool
  // after |Receiver::OnFrameReadyInBuffer| is invoked.
  base::RunLoop wait_loop;
  mojom::ReceiverPtr receiver_proxy;
  MockReceiver receiver(mojo::MakeRequest(&receiver_proxy));
  EXPECT_CALL(receiver, OnStarted());
  EXPECT_CALL(receiver, DoOnNewBuffer(_, _))
      .Times(
          SharedMemoryVirtualDeviceMojoAdapter::max_buffer_pool_buffer_count());
  EXPECT_CALL(receiver, DoOnFrameReadyInBuffer(_, _, _, _))
      .Times(
          SharedMemoryVirtualDeviceMojoAdapter::max_buffer_pool_buffer_count());
  device_adapter_->Start(media::VideoCaptureParams(),
                         std::move(receiver_proxy));
  for (auto buffer_id : received_buffer_ids_) {
    media::mojom::VideoFrameInfoPtr info = media::mojom::VideoFrameInfo::New();
    info->metadata = base::Value(base::Value::Type::DICTIONARY);
    device_adapter_->OnFrameReadyInBuffer(buffer_id, std::move(info));
  }
  wait_loop.RunUntilIdle();
  Mock::VerifyAndClearExpectations(&receiver);

  // Verify that requesting a buffer doesn't create a new one, will reuse
  // the available buffer in the pool.
  base::RunLoop wait_loop2;
  EXPECT_CALL(*producer_, DoOnNewBuffer(_, _, _)).Times(0);
  base::MockCallback<
      mojom::SharedMemoryVirtualDevice::RequestFrameBufferCallback>
      request_frame_buffer_callback;
  EXPECT_CALL(request_frame_buffer_callback, Run(_))
      .Times(1)
      .WillOnce(Invoke([this](int32_t buffer_id) {
        // Verify that the returned |buffer_id| is a known buffer ID.
        EXPECT_TRUE(base::ContainsValue(received_buffer_ids_, buffer_id));
      }));
  device_adapter_->RequestFrameBuffer(kTestFrameSize, kTestPixelFormat, nullptr,
                                      request_frame_buffer_callback.Get());
  wait_loop2.RunUntilIdle();

  // Verify that when stopping the device, the receiver receives calls to
  // OnBufferRetired() followed by a single call to OnStopped().
  base::RunLoop wait_for_stopped_loop;
  {
    testing::InSequence s;
    EXPECT_CALL(receiver, DoOnBufferRetired(_))
        .Times(SharedMemoryVirtualDeviceMojoAdapter::
                   max_buffer_pool_buffer_count());
    EXPECT_CALL(receiver, OnStopped())
        .WillOnce(Invoke(
            [&wait_for_stopped_loop]() { wait_for_stopped_loop.Quit(); }));
  }
  device_adapter_->Stop();
  wait_for_stopped_loop.Run();
}

}  // namespace video_capture
