// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/capture/video/chromeos/request_manager.h"

#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
#include "media/capture/video/blob_utils.h"
#include "media/capture/video/chromeos/camera_buffer_factory.h"
#include "media/capture/video/chromeos/camera_device_context.h"
#include "media/capture/video/chromeos/camera_device_delegate.h"
#include "media/capture/video/chromeos/mock_video_capture_client.h"
#include "media/capture/video/chromeos/stream_buffer_manager.h"
#include "media/capture/video/mock_gpu_memory_buffer_manager.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::A;
using testing::AtLeast;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::Return;

namespace media {

namespace {

class MockStreamCaptureInterface : public StreamCaptureInterface {
 public:
  void ProcessCaptureRequest(
      cros::mojom::Camera3CaptureRequestPtr request,
      base::OnceCallback<void(int32_t)> callback) override {
    DoProcessCaptureRequest(request, callback);
  }
  MOCK_METHOD2(DoProcessCaptureRequest,
               void(cros::mojom::Camera3CaptureRequestPtr& request,
                    base::OnceCallback<void(int32_t)>& callback));

  void Flush(base::OnceCallback<void(int32_t)> callback) override {
    DoFlush(callback);
  }
  MOCK_METHOD1(DoFlush, void(base::OnceCallback<void(int32_t)>& callback));
};

const VideoCaptureFormat kDefaultCaptureFormat(gfx::Size(1280, 720),
                                               30.0,
                                               PIXEL_FORMAT_NV12);

class FakeCameraBufferFactory : public CameraBufferFactory {
 public:
  FakeCameraBufferFactory() {
    gpu_memory_buffer_manager_ =
        std::make_unique<unittest_internal::MockGpuMemoryBufferManager>();
  }
  std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
      const gfx::Size& size,
      gfx::BufferFormat format,
      gfx::BufferUsage usage) override {
    return unittest_internal::MockGpuMemoryBufferManager::
        CreateFakeGpuMemoryBuffer(size, format, usage, gpu::kNullSurfaceHandle,
                                  nullptr);
  }

  ChromiumPixelFormat ResolveStreamBufferFormat(
      cros::mojom::HalPixelFormat hal_format,
      gfx::BufferUsage usage) override {
    return ChromiumPixelFormat{PIXEL_FORMAT_NV12,
                               gfx::BufferFormat::YUV_420_BIPLANAR};
  }

 private:
  std::unique_ptr<unittest_internal::MockGpuMemoryBufferManager>
      gpu_memory_buffer_manager_;
};

}  // namespace

class RequestManagerTest : public ::testing::Test {
 public:
  void SetUp() override {
    quit_ = false;
    client_type_ = ClientType::kPreviewClient;
    VideoCaptureParams params;
    params.requested_format = kDefaultCaptureFormat;
    capture_params_[client_type_] = params;
    device_context_ = std::make_unique<CameraDeviceContext>();
    if (device_context_->AddClient(
            client_type_,
            std::make_unique<unittest_internal::MockVideoCaptureClient>())) {
      std::string fake_device_id = "0";
      request_manager_ = std::make_unique<RequestManager>(
          fake_device_id, mock_callback_ops_.BindNewPipeAndPassReceiver(),
          std::make_unique<MockStreamCaptureInterface>(), device_context_.get(),
          VideoCaptureBufferType::kSharedMemory,
          std::make_unique<FakeCameraBufferFactory>(),
          base::BindRepeating(
              [](const uint8_t* buffer, const uint32_t bytesused,
                 const VideoCaptureFormat& capture_format,
                 const int rotation) { return mojom::Blob::New(); }),
          base::SingleThreadTaskRunner::GetCurrentDefault(),
          cros::mojom::CAMERA_DEVICE_API_VERSION_3_5);
    }
  }

  void TearDown() override {
    device_context_->RemoveClient(client_type_);
    request_manager_.reset();
  }

  void DoLoop() {
    run_loop_ = std::make_unique<base::RunLoop>();
    run_loop_->Run();
  }

  void QuitCaptureLoop() {
    quit_ = true;
    if (run_loop_) {
      run_loop_->Quit();
    }
  }

  cros::mojom::CameraMetadataPtr GetFakeStaticMetadata(
      int32_t partial_result_count) {
    cros::mojom::CameraMetadataPtr static_metadata =
        cros::mojom::CameraMetadata::New();
    static_metadata->entry_count = 2;
    static_metadata->entry_capacity = 2;
    static_metadata->entries =
        std::vector<cros::mojom::CameraMetadataEntryPtr>();

    cros::mojom::CameraMetadataEntryPtr entry =
        cros::mojom::CameraMetadataEntry::New();
    entry->index = 0;
    entry->tag =
        cros::mojom::CameraMetadataTag::ANDROID_REQUEST_PARTIAL_RESULT_COUNT;
    entry->type = cros::mojom::EntryType::TYPE_INT32;
    entry->count = 1;
    uint8_t* as_int8 = reinterpret_cast<uint8_t*>(&partial_result_count);
    entry->data.assign(as_int8, as_int8 + entry->count * sizeof(int32_t));
    static_metadata->entries->push_back(std::move(entry));

    entry = cros::mojom::CameraMetadataEntry::New();
    entry->index = 1;
    entry->tag = cros::mojom::CameraMetadataTag::ANDROID_JPEG_MAX_SIZE;
    entry->type = cros::mojom::EntryType::TYPE_INT32;
    entry->count = 1;
    int32_t jpeg_max_size = 65535;
    as_int8 = reinterpret_cast<uint8_t*>(&jpeg_max_size);
    entry->data.assign(as_int8, as_int8 + entry->count * sizeof(int32_t));
    static_metadata->entries->push_back(std::move(entry));

    entry = cros::mojom::CameraMetadataEntry::New();
    entry->index = 2;
    entry->tag =
        cros::mojom::CameraMetadataTag::ANDROID_REQUEST_PIPELINE_MAX_DEPTH;
    entry->type = cros::mojom::EntryType::TYPE_BYTE;
    entry->count = 1;
    uint8_t pipeline_max_depth = 1;
    entry->data.assign(&pipeline_max_depth,
                       &pipeline_max_depth + entry->count * sizeof(uint8_t));
    static_metadata->entries->push_back(std::move(entry));

    return static_metadata;
  }

  void ProcessCaptureRequest(cros::mojom::Camera3CaptureRequestPtr& request,
                             base::OnceCallback<void(int32_t)>& callback) {
    if (quit_) {
      return;
    }
    std::move(callback).Run(0);
    mock_callback_ops_->Notify(PrepareShutterNotifyMessage(
        request->frame_number,
        (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()));
    mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult(
        request->frame_number, cros::mojom::CameraMetadata::New(), 1,
        std::move(request->output_buffers)));
  }

  MockStreamCaptureInterface* GetMockCaptureInterface() {
    EXPECT_NE(nullptr, request_manager_.get());
    return reinterpret_cast<MockStreamCaptureInterface*>(
        request_manager_->capture_interface_.get());
  }

  unittest_internal::MockVideoCaptureClient* GetMockVideoCaptureClient() {
    EXPECT_NE(nullptr, device_context_);
    base::AutoLock lock(device_context_->client_lock_);
    EXPECT_TRUE(!device_context_->clients_.empty());
    return reinterpret_cast<unittest_internal::MockVideoCaptureClient*>(
        device_context_->clients_[client_type_].get());
  }

  std::map<uint32_t, RequestManager::CaptureResult>& GetPendingResults() {
    EXPECT_NE(nullptr, request_manager_.get());
    return request_manager_->pending_results_;
  }

  std::vector<cros::mojom::Camera3StreamPtr> PrepareCaptureStream(
      uint32_t max_buffers) {
    std::vector<cros::mojom::Camera3StreamPtr> streams;

    auto preview_stream = cros::mojom::Camera3Stream::New();
    preview_stream->id = static_cast<uint64_t>(StreamType::kPreviewOutput);
    preview_stream->stream_type =
        cros::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
    preview_stream->width = kDefaultCaptureFormat.frame_size.width();
    preview_stream->height = kDefaultCaptureFormat.frame_size.height();
    preview_stream->format =
        cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888;
    preview_stream->usage = 0;
    preview_stream->max_buffers = max_buffers;
    preview_stream->data_space = 0;
    preview_stream->rotation =
        cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
    streams.push_back(std::move(preview_stream));

    auto still_capture_stream = cros::mojom::Camera3Stream::New();
    still_capture_stream->id = static_cast<uint64_t>(StreamType::kJpegOutput);
    still_capture_stream->stream_type =
        cros::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
    still_capture_stream->width = kDefaultCaptureFormat.frame_size.width();
    still_capture_stream->height = kDefaultCaptureFormat.frame_size.height();
    still_capture_stream->format =
        cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_BLOB;
    still_capture_stream->usage = 0;
    still_capture_stream->max_buffers = max_buffers;
    still_capture_stream->data_space = 0;
    still_capture_stream->rotation =
        cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
    streams.push_back(std::move(still_capture_stream));

    return streams;
  }

  cros::mojom::Camera3NotifyMsgPtr PrepareErrorNotifyMessage(
      uint32_t frame_number,
      cros::mojom::Camera3ErrorMsgCode error_code) {
    auto error_msg = cros::mojom::Camera3ErrorMsg::New();
    error_msg->frame_number = frame_number;
    // There is only the preview stream.
    error_msg->error_stream_id =
        static_cast<uint64_t>(StreamType::kPreviewOutput);
    error_msg->error_code = error_code;
    auto notify_msg = cros::mojom::Camera3NotifyMsg::New();
    notify_msg->type = cros::mojom::Camera3MsgType::CAMERA3_MSG_ERROR;
    notify_msg->message =
        cros::mojom::Camera3NotifyMsgMessage::NewError(std::move(error_msg));
    return notify_msg;
  }

  cros::mojom::Camera3NotifyMsgPtr PrepareShutterNotifyMessage(
      uint32_t frame_number,
      uint64_t timestamp) {
    auto shutter_msg = cros::mojom::Camera3ShutterMsg::New();
    shutter_msg->frame_number = frame_number;
    shutter_msg->timestamp = timestamp;
    auto notify_msg = cros::mojom::Camera3NotifyMsg::New();
    notify_msg->type = cros::mojom::Camera3MsgType::CAMERA3_MSG_SHUTTER;
    notify_msg->message = cros::mojom::Camera3NotifyMsgMessage::NewShutter(
        std::move(shutter_msg));
    return notify_msg;
  }

  cros::mojom::Camera3CaptureResultPtr PrepareCapturedResult(
      uint32_t frame_number,
      cros::mojom::CameraMetadataPtr result_metadata,
      uint32_t partial_result,
      std::vector<cros::mojom::Camera3StreamBufferPtr> output_buffers) {
    auto result = cros::mojom::Camera3CaptureResult::New();
    result->frame_number = frame_number;
    result->result = std::move(result_metadata);
    if (output_buffers.size()) {
      result->output_buffers = std::move(output_buffers);
    }
    result->partial_result = partial_result;
    return result;
  }

 protected:
  std::unique_ptr<RequestManager> request_manager_;
  mojo::Remote<cros::mojom::Camera3CallbackOps> mock_callback_ops_;
  std::unique_ptr<CameraDeviceContext> device_context_;
  ClientType client_type_;
  base::flat_map<ClientType, VideoCaptureParams> capture_params_;

 private:
  std::unique_ptr<base::RunLoop> run_loop_;
  bool quit_;
  base::test::TaskEnvironment scoped_test_environment_;
};

// A basic sanity test to capture one frame with the capture loop.
TEST_F(RequestManagerTest, SimpleCaptureTest) {
  GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce(
      &RequestManagerTest::QuitCaptureLoop, base::Unretained(this)));
  EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _))
      .Times(AtLeast(1))
      .WillRepeatedly(Invoke(this, &RequestManagerTest::ProcessCaptureRequest));

  request_manager_->SetUpStreamsAndBuffers(
      capture_params_, GetFakeStaticMetadata(/* partial_result_count */ 1),
      PrepareCaptureStream(/* max_buffers */ 1));
  request_manager_->StartPreview(cros::mojom::CameraMetadata::New());

  // Wait until a captured frame is received by MockVideoCaptureClient.
  DoLoop();
}

// Test that the RequestManager submits a captured result only after all
// partial metadata are received.
TEST_F(RequestManagerTest, PartialResultTest) {
  GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce(
      [](RequestManagerTest* test) {
        EXPECT_EQ(1u, test->GetPendingResults().size());
        // Make sure all the three partial metadata are received before the
        // captured result is submitted.
        EXPECT_EQ(
            3u, test->GetPendingResults()[0].partial_metadata_received.size());
        test->QuitCaptureLoop();
      },
      base::Unretained(this)));
  EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _))
      .Times(AtLeast(1))
      .WillRepeatedly(
          Invoke([this](cros::mojom::Camera3CaptureRequestPtr& request,
                        base::OnceCallback<void(int32_t)>& callback) {
            std::move(callback).Run(0);
            mock_callback_ops_->Notify(PrepareShutterNotifyMessage(
                request->frame_number,
                (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()));
            mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult(
                request->frame_number, cros::mojom::CameraMetadata::New(), 1,
                std::move(request->output_buffers)));
            mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult(
                request->frame_number, cros::mojom::CameraMetadata::New(), 2,
                std::vector<cros::mojom::Camera3StreamBufferPtr>()));
            mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult(
                request->frame_number, cros::mojom::CameraMetadata::New(), 3,
                std::vector<cros::mojom::Camera3StreamBufferPtr>()));
          }));

  request_manager_->SetUpStreamsAndBuffers(
      capture_params_, GetFakeStaticMetadata(/* partial_result_count */ 3),
      PrepareCaptureStream(/* max_buffers */ 1));
  request_manager_->StartPreview(cros::mojom::CameraMetadata::New());

  // Wait until a captured frame is received by MockVideoCaptureClient.
  DoLoop();
}

// Test that the capture loop is stopped and no frame is submitted when a device
// error happens.
TEST_F(RequestManagerTest, DeviceErrorTest) {
  GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce(
      [](RequestManagerTest* test) {
        ADD_FAILURE() << "No frame should be submitted";
        test->QuitCaptureLoop();
      },
      base::Unretained(this)));
  EXPECT_CALL(*GetMockVideoCaptureClient(), OnError(_, _, _))
      .Times(1)
      .WillOnce(InvokeWithoutArgs(this, &RequestManagerTest::QuitCaptureLoop));
  EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _))
      .Times(1)
      .WillOnce(Invoke([this](cros::mojom::Camera3CaptureRequestPtr& request,
                              base::OnceCallback<void(int32_t)>& callback) {
        std::move(callback).Run(0);
        mock_callback_ops_->Notify(PrepareErrorNotifyMessage(
            request->frame_number,
            cros::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_DEVICE));
      }));

  request_manager_->SetUpStreamsAndBuffers(
      capture_params_, GetFakeStaticMetadata(/* partial_result_count */ 1),
      PrepareCaptureStream(/* max_buffers */ 1));
  request_manager_->StartPreview(cros::mojom::CameraMetadata::New());

  // Wait until the MockVideoCaptureClient is deleted.
  DoLoop();
}

// Test that upon request error the erroneous frame is dropped, and the capture
// loop continues.
TEST_F(RequestManagerTest, RequestErrorTest) {
  GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce(
      [](RequestManagerTest* test) {
        // Frame 0 should be dropped, and the frame callback should be called
        // with frame 1.
        EXPECT_EQ(test->GetPendingResults().end(),
                  test->GetPendingResults().find(0));
        EXPECT_NE(test->GetPendingResults().end(),
                  test->GetPendingResults().find(1));
        test->QuitCaptureLoop();
      },
      base::Unretained(this)));
  EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _))
      .Times(AtLeast(2))
      .WillOnce(Invoke([this](cros::mojom::Camera3CaptureRequestPtr& request,
                              base::OnceCallback<void(int32_t)>& callback) {
        std::move(callback).Run(0);
        mock_callback_ops_->Notify(PrepareErrorNotifyMessage(
            request->frame_number,
            cros::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_REQUEST));
        request->output_buffers[0]->status =
            cros::mojom::Camera3BufferStatus::CAMERA3_BUFFER_STATUS_ERROR;
        mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult(
            request->frame_number, cros::mojom::CameraMetadata::New(), 1,
            std::move(request->output_buffers)));
      }))
      .WillRepeatedly(Invoke(this, &RequestManagerTest::ProcessCaptureRequest));

  request_manager_->SetUpStreamsAndBuffers(
      capture_params_, GetFakeStaticMetadata(/* partial_result_count */ 1),
      PrepareCaptureStream(/* max_buffers */ 1));
  request_manager_->StartPreview(cros::mojom::CameraMetadata::New());

  // Wait until the MockVideoCaptureClient is deleted.
  DoLoop();
}

// Test that upon result error the captured buffer is submitted despite of the
// missing result metadata, and the capture loop continues.
TEST_F(RequestManagerTest, ResultErrorTest) {
  GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce(
      [](RequestManagerTest* test) {
        // Frame 0 should be submitted.
        EXPECT_NE(test->GetPendingResults().end(),
                  test->GetPendingResults().find(0));
        test->QuitCaptureLoop();
      },
      base::Unretained(this)));
  EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _))
      .Times(AtLeast(1))
      .WillOnce(Invoke([this](cros::mojom::Camera3CaptureRequestPtr& request,
                              base::OnceCallback<void(int32_t)>& callback) {
        std::move(callback).Run(0);
        mock_callback_ops_->Notify(PrepareShutterNotifyMessage(
            request->frame_number,
            (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()));
        mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult(
            request->frame_number, cros::mojom::CameraMetadata::New(), 1,
            std::move(request->output_buffers)));
        // Send a result error notify without sending the second partial result.
        // RequestManager should submit the buffer when it receives the
        // result error.
        mock_callback_ops_->Notify(PrepareErrorNotifyMessage(
            request->frame_number,
            cros::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_RESULT));
      }))
      .WillRepeatedly(Invoke(this, &RequestManagerTest::ProcessCaptureRequest));

  request_manager_->SetUpStreamsAndBuffers(
      capture_params_, GetFakeStaticMetadata(/* partial_result_count */ 2),
      PrepareCaptureStream(/* max_buffers */ 1));
  request_manager_->StartPreview(cros::mojom::CameraMetadata::New());

  // Wait until the MockVideoCaptureClient is deleted.
  DoLoop();
}

// Test that upon buffer error the erroneous buffer is dropped, and the capture
// loop continues.
TEST_F(RequestManagerTest, BufferErrorTest) {
  GetMockVideoCaptureClient()->SetFrameCb(base::BindOnce(
      [](RequestManagerTest* test) {
        // Frame 0 should be dropped, and the frame callback should be called
        // with frame 1.
        EXPECT_EQ(test->GetPendingResults().end(),
                  test->GetPendingResults().find(0));
        EXPECT_NE(test->GetPendingResults().end(),
                  test->GetPendingResults().find(1));
        test->QuitCaptureLoop();
      },
      base::Unretained(this)));
  EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _))
      .Times(AtLeast(2))
      .WillOnce(Invoke([this](cros::mojom::Camera3CaptureRequestPtr& request,
                              base::OnceCallback<void(int32_t)>& callback) {
        std::move(callback).Run(0);
        mock_callback_ops_->Notify(PrepareShutterNotifyMessage(
            request->frame_number,
            (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()));
        mock_callback_ops_->Notify(PrepareErrorNotifyMessage(
            request->frame_number,
            cros::mojom::Camera3ErrorMsgCode::CAMERA3_MSG_ERROR_BUFFER));
        request->output_buffers[0]->status =
            cros::mojom::Camera3BufferStatus::CAMERA3_BUFFER_STATUS_ERROR;
        mock_callback_ops_->ProcessCaptureResult(PrepareCapturedResult(
            request->frame_number, cros::mojom::CameraMetadata::New(), 1,
            std::move(request->output_buffers)));
      }))
      .WillRepeatedly(Invoke(this, &RequestManagerTest::ProcessCaptureRequest));

  request_manager_->SetUpStreamsAndBuffers(
      capture_params_, GetFakeStaticMetadata(/* partial_result_count */ 1),
      PrepareCaptureStream(/* max_buffers */ 1));
  request_manager_->StartPreview(cros::mojom::CameraMetadata::New());

  // Wait until the MockVideoCaptureClient is deleted.
  DoLoop();
}

// Test that preview and still capture buffers can be correctly submitted.
// TODO(crbug.com/917574): Add reprocess tests and take photo test.

}  // namespace media
