// Copyright 2013 The Flutter 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 "capture_controller.h"

#include <flutter/method_call.h>
#include <flutter/method_result_functions.h>
#include <flutter/standard_method_codec.h>
#include <flutter/texture_registrar.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <windows.h>
#include <wrl/client.h>

#include <functional>
#include <memory>
#include <string>

#include "mocks.h"
#include "string_utils.h"

namespace camera_windows {

namespace test {

using Microsoft::WRL::ComPtr;
using ::testing::_;
using ::testing::Eq;
using ::testing::Return;

void MockInitCaptureController(CaptureControllerImpl* capture_controller,
                               MockTextureRegistrar* texture_registrar,
                               MockCaptureEngine* engine, MockCamera* camera,
                               int64_t mock_texture_id) {
  ComPtr<MockMediaSource> video_source = new MockMediaSource();
  ComPtr<MockMediaSource> audio_source = new MockMediaSource();

  capture_controller->SetCaptureEngine(
      reinterpret_cast<IMFCaptureEngine*>(engine));
  capture_controller->SetVideoSource(
      reinterpret_cast<IMFMediaSource*>(video_source.Get()));
  capture_controller->SetAudioSource(
      reinterpret_cast<IMFMediaSource*>(audio_source.Get()));

  EXPECT_CALL(*texture_registrar, RegisterTexture)
      .Times(1)
      .WillOnce([reg = texture_registrar,
                 mock_texture_id](flutter::TextureVariant* texture) -> int64_t {
        EXPECT_TRUE(texture);
        reg->texture_ = texture;
        reg->texture_id_ = mock_texture_id;
        return reg->texture_id_;
      });
  EXPECT_CALL(*texture_registrar, UnregisterTexture(Eq(mock_texture_id)))
      .Times(1);
  EXPECT_CALL(*camera, OnCreateCaptureEngineFailed).Times(0);
  EXPECT_CALL(*camera, OnCreateCaptureEngineSucceeded(Eq(mock_texture_id)))
      .Times(1);
  EXPECT_CALL(*engine, Initialize).Times(1);

  bool result = capture_controller->InitCaptureDevice(
      texture_registrar, MOCK_DEVICE_ID, true, ResolutionPreset::kAuto);

  EXPECT_TRUE(result);

  // MockCaptureEngine::Initialize is called
  EXPECT_TRUE(engine->initialized_);

  engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_INITIALIZED);
}

void MockStartPreview(CaptureControllerImpl* capture_controller,
                      MockCaptureSource* capture_source,
                      MockCapturePreviewSink* preview_sink,
                      MockTextureRegistrar* texture_registrar,
                      MockCaptureEngine* engine, MockCamera* camera,
                      std::unique_ptr<uint8_t[]> mock_source_buffer,
                      uint32_t mock_source_buffer_size,
                      uint32_t mock_preview_width, uint32_t mock_preview_height,
                      int64_t mock_texture_id) {
  EXPECT_CALL(*engine, GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_PREVIEW, _))
      .Times(1)
      .WillOnce([src_sink = preview_sink](MF_CAPTURE_ENGINE_SINK_TYPE sink_type,
                                          IMFCaptureSink** target_sink) {
        *target_sink = src_sink;
        src_sink->AddRef();
        return S_OK;
      });

  EXPECT_CALL(*preview_sink, RemoveAllStreams).Times(1).WillOnce(Return(S_OK));
  EXPECT_CALL(*preview_sink, AddStream).Times(1).WillOnce(Return(S_OK));
  EXPECT_CALL(*preview_sink, SetSampleCallback)
      .Times(1)
      .WillOnce([sink = preview_sink](
                    DWORD dwStreamSinkIndex,
                    IMFCaptureEngineOnSampleCallback* pCallback) -> HRESULT {
        sink->sample_callback_ = pCallback;
        return S_OK;
      });

  EXPECT_CALL(*engine, GetSource)
      .Times(1)
      .WillOnce(
          [src_source = capture_source](IMFCaptureSource** target_source) {
            *target_source = src_source;
            src_source->AddRef();
            return S_OK;
          });

  EXPECT_CALL(
      *capture_source,
      GetAvailableDeviceMediaType(
          Eq((DWORD)
                 MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_PREVIEW),
          _, _))
      .WillRepeatedly([mock_preview_width, mock_preview_height](
                          DWORD stream_index, DWORD media_type_index,
                          IMFMediaType** media_type) {
        // We give only one media type to loop through
        if (media_type_index != 0) return MF_E_NO_MORE_TYPES;
        *media_type =
            new FakeMediaType(MFMediaType_Video, MFVideoFormat_RGB32,
                              mock_preview_width, mock_preview_height);
        (*media_type)->AddRef();
        return S_OK;
      });

  EXPECT_CALL(
      *capture_source,
      GetAvailableDeviceMediaType(
          Eq((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_RECORD),
          _, _))
      .WillRepeatedly([mock_preview_width, mock_preview_height](
                          DWORD stream_index, DWORD media_type_index,
                          IMFMediaType** media_type) {
        // We give only one media type to loop through
        if (media_type_index != 0) return MF_E_NO_MORE_TYPES;
        *media_type =
            new FakeMediaType(MFMediaType_Video, MFVideoFormat_RGB32,
                              mock_preview_width, mock_preview_height);
        (*media_type)->AddRef();
        return S_OK;
      });

  EXPECT_CALL(*engine, StartPreview()).Times(1).WillOnce(Return(S_OK));

  // Called by destructor
  EXPECT_CALL(*engine, StopPreview()).Times(1).WillOnce(Return(S_OK));

  // Called after first processed sample
  EXPECT_CALL(*camera,
              OnStartPreviewSucceeded(mock_preview_width, mock_preview_height))
      .Times(1);
  EXPECT_CALL(*camera, OnStartPreviewFailed).Times(0);
  EXPECT_CALL(*texture_registrar, MarkTextureFrameAvailable(mock_texture_id))
      .Times(1);

  capture_controller->StartPreview();

  EXPECT_EQ(capture_controller->GetPreviewHeight(), mock_preview_height);
  EXPECT_EQ(capture_controller->GetPreviewWidth(), mock_preview_width);

  // Capture engine is now started and will first send event of started preview
  engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_PREVIEW_STARTED);

  // SendFake sample
  preview_sink->SendFakeSample(mock_source_buffer.get(),
                               mock_source_buffer_size);
}

void MockRecordStart(CaptureControllerImpl* capture_controller,
                     MockCaptureEngine* engine,
                     MockCaptureRecordSink* record_sink, MockCamera* camera,
                     const std::string& mock_path_to_video) {
  EXPECT_CALL(*engine, StartRecord()).Times(1).WillOnce(Return(S_OK));

  EXPECT_CALL(*engine, GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_RECORD, _))
      .Times(1)
      .WillOnce([src_sink = record_sink](MF_CAPTURE_ENGINE_SINK_TYPE sink_type,
                                         IMFCaptureSink** target_sink) {
        *target_sink = src_sink;
        src_sink->AddRef();
        return S_OK;
      });

  EXPECT_CALL(*record_sink, RemoveAllStreams).Times(1).WillOnce(Return(S_OK));
  EXPECT_CALL(*record_sink, AddStream).Times(2).WillRepeatedly(Return(S_OK));
  EXPECT_CALL(*record_sink, SetOutputFileName).Times(1).WillOnce(Return(S_OK));

  capture_controller->StartRecord(mock_path_to_video, -1);

  EXPECT_CALL(*camera, OnStartRecordSucceeded()).Times(1);
  engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_RECORD_STARTED);
}

TEST(CaptureController,
     InitCaptureEngineCallsOnCreateCaptureEngineSucceededWithTextureId) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  uint64_t mock_texture_id = 1234;

  // Init capture controller with mocks and tests
  MockInitCaptureController(capture_controller.get(), texture_registrar.get(),
                            engine.Get(), camera.get(), mock_texture_id);

  capture_controller = nullptr;
  camera = nullptr;
  texture_registrar = nullptr;
  engine = nullptr;
}

TEST(CaptureController, InitCaptureEngineCanOnlyBeCalledOnce) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  uint64_t mock_texture_id = 1234;

  // Init capture controller once with mocks and tests
  MockInitCaptureController(capture_controller.get(), texture_registrar.get(),
                            engine.Get(), camera.get(), mock_texture_id);

  // Init capture controller a second time.
  EXPECT_CALL(*camera, OnCreateCaptureEngineFailed).Times(1);

  bool result = capture_controller->InitCaptureDevice(
      texture_registrar.get(), MOCK_DEVICE_ID, true, ResolutionPreset::kAuto);

  EXPECT_FALSE(result);

  capture_controller = nullptr;
  camera = nullptr;
  texture_registrar = nullptr;
  engine = nullptr;
}

TEST(CaptureController, InitCaptureEngineReportsFailure) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  ComPtr<MockMediaSource> video_source = new MockMediaSource();
  ComPtr<MockMediaSource> audio_source = new MockMediaSource();

  capture_controller->SetCaptureEngine(
      reinterpret_cast<IMFCaptureEngine*>(engine.Get()));
  capture_controller->SetVideoSource(
      reinterpret_cast<IMFMediaSource*>(video_source.Get()));
  capture_controller->SetAudioSource(
      reinterpret_cast<IMFMediaSource*>(audio_source.Get()));

  EXPECT_CALL(*texture_registrar, RegisterTexture).Times(0);
  EXPECT_CALL(*texture_registrar, UnregisterTexture).Times(0);
  EXPECT_CALL(*camera, OnCreateCaptureEngineSucceeded).Times(0);

  EXPECT_CALL(*engine.Get(), Initialize)
      .Times(1)
      .WillOnce(Return(E_ACCESSDENIED));

  EXPECT_CALL(*camera,
              OnCreateCaptureEngineFailed(Eq("Failed to create camera")))
      .Times(1);

  bool result = capture_controller->InitCaptureDevice(
      texture_registrar.get(), MOCK_DEVICE_ID, true, ResolutionPreset::kAuto);

  EXPECT_FALSE(result);
  EXPECT_FALSE(engine->initialized_);

  capture_controller = nullptr;
  camera = nullptr;
  texture_registrar = nullptr;
  engine = nullptr;
}

TEST(CaptureController, StartPreviewStartsProcessingSamples) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  uint64_t mock_texture_id = 1234;

  // Initialize capture controller to be able to start preview
  MockInitCaptureController(capture_controller.get(), texture_registrar.get(),
                            engine.Get(), camera.get(), mock_texture_id);

  ComPtr<MockCapturePreviewSink> preview_sink = new MockCapturePreviewSink();
  ComPtr<MockCaptureSource> capture_source = new MockCaptureSource();

  // Let's keep these small for mock texture data. Two pixels should be
  // enough.
  uint32_t mock_preview_width = 2;
  uint32_t mock_preview_height = 1;
  uint32_t pixels_total = mock_preview_width * mock_preview_height;
  uint32_t pixel_size = 4;

  // Build mock texture
  uint32_t mock_texture_data_size = pixels_total * pixel_size;

  std::unique_ptr<uint8_t[]> mock_source_buffer =
      std::make_unique<uint8_t[]>(mock_texture_data_size);

  uint8_t mock_red_pixel = 0x11;
  uint8_t mock_green_pixel = 0x22;
  uint8_t mock_blue_pixel = 0x33;
  MFVideoFormatRGB32Pixel* mock_source_buffer_data =
      (MFVideoFormatRGB32Pixel*)mock_source_buffer.get();

  for (uint32_t i = 0; i < pixels_total; i++) {
    mock_source_buffer_data[i].r = mock_red_pixel;
    mock_source_buffer_data[i].g = mock_green_pixel;
    mock_source_buffer_data[i].b = mock_blue_pixel;
  }

  // Start preview and run preview tests
  MockStartPreview(capture_controller.get(), capture_source.Get(),
                   preview_sink.Get(), texture_registrar.get(), engine.Get(),
                   camera.get(), std::move(mock_source_buffer),
                   mock_texture_data_size, mock_preview_width,
                   mock_preview_height, mock_texture_id);

  // Test texture processing
  EXPECT_TRUE(texture_registrar->texture_);
  if (texture_registrar->texture_) {
    auto pixel_buffer_texture =
        std::get_if<flutter::PixelBufferTexture>(texture_registrar->texture_);
    EXPECT_TRUE(pixel_buffer_texture);

    if (pixel_buffer_texture) {
      auto converted_buffer =
          pixel_buffer_texture->CopyPixelBuffer((size_t)100, (size_t)100);

      EXPECT_TRUE(converted_buffer);
      if (converted_buffer) {
        EXPECT_EQ(converted_buffer->height, mock_preview_height);
        EXPECT_EQ(converted_buffer->width, mock_preview_width);

        FlutterDesktopPixel* converted_buffer_data =
            (FlutterDesktopPixel*)(converted_buffer->buffer);

        for (uint32_t i = 0; i < pixels_total; i++) {
          EXPECT_EQ(converted_buffer_data[i].r, mock_red_pixel);
          EXPECT_EQ(converted_buffer_data[i].g, mock_green_pixel);
          EXPECT_EQ(converted_buffer_data[i].b, mock_blue_pixel);
        }

        // Call release callback to get mutex lock unlocked.
        converted_buffer->release_callback(converted_buffer->release_context);
      }
      converted_buffer = nullptr;
    }
    pixel_buffer_texture = nullptr;
  }

  capture_controller = nullptr;
  engine = nullptr;
  camera = nullptr;
  texture_registrar = nullptr;
}

TEST(CaptureController, StartRecordSuccess) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  uint64_t mock_texture_id = 1234;

  // Initialize capture controller to be able to start preview
  MockInitCaptureController(capture_controller.get(), texture_registrar.get(),
                            engine.Get(), camera.get(), mock_texture_id);

  ComPtr<MockCapturePreviewSink> preview_sink = new MockCapturePreviewSink();
  ComPtr<MockCaptureSource> capture_source = new MockCaptureSource();

  std::unique_ptr<uint8_t[]> mock_source_buffer =
      std::make_unique<uint8_t[]>(0);

  // Start preview to be able to start record
  MockStartPreview(capture_controller.get(), capture_source.Get(),
                   preview_sink.Get(), texture_registrar.get(), engine.Get(),
                   camera.get(), std::move(mock_source_buffer), 0, 1, 1,
                   mock_texture_id);

  // Start record
  ComPtr<MockCaptureRecordSink> record_sink = new MockCaptureRecordSink();
  std::string mock_path_to_video = "mock_path_to_video";
  MockRecordStart(capture_controller.get(), engine.Get(), record_sink.Get(),
                  camera.get(), mock_path_to_video);

  // Called by destructor
  EXPECT_CALL(*(engine.Get()), StopRecord(true, false))
      .Times(1)
      .WillOnce(Return(S_OK));

  capture_controller = nullptr;
  texture_registrar = nullptr;
  engine = nullptr;
  camera = nullptr;
  record_sink = nullptr;
}

TEST(CaptureController, StopRecordSuccess) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  uint64_t mock_texture_id = 1234;

  // Initialize capture controller to be able to start preview
  MockInitCaptureController(capture_controller.get(), texture_registrar.get(),
                            engine.Get(), camera.get(), mock_texture_id);

  ComPtr<MockCapturePreviewSink> preview_sink = new MockCapturePreviewSink();
  ComPtr<MockCaptureSource> capture_source = new MockCaptureSource();

  std::unique_ptr<uint8_t[]> mock_source_buffer =
      std::make_unique<uint8_t[]>(0);

  // Start preview to be able to start record
  MockStartPreview(capture_controller.get(), capture_source.Get(),
                   preview_sink.Get(), texture_registrar.get(), engine.Get(),
                   camera.get(), std::move(mock_source_buffer), 0, 1, 1,
                   mock_texture_id);

  // Start record
  ComPtr<MockCaptureRecordSink> record_sink = new MockCaptureRecordSink();
  std::string mock_path_to_video = "mock_path_to_video";
  MockRecordStart(capture_controller.get(), engine.Get(), record_sink.Get(),
                  camera.get(), mock_path_to_video);

  // Request to stop record
  EXPECT_CALL(*(engine.Get()), StopRecord(true, false))
      .Times(1)
      .WillOnce(Return(S_OK));
  capture_controller->StopRecord();

  // OnStopRecordSucceeded should be called with mocked file path
  EXPECT_CALL(*camera, OnStopRecordSucceeded(Eq(mock_path_to_video))).Times(1);
  engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_RECORD_STOPPED);

  capture_controller = nullptr;
  texture_registrar = nullptr;
  engine = nullptr;
  camera = nullptr;
  record_sink = nullptr;
}

TEST(CaptureController, TakePictureSuccess) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  uint64_t mock_texture_id = 1234;

  // Initialize capture controller to be able to start preview
  MockInitCaptureController(capture_controller.get(), texture_registrar.get(),
                            engine.Get(), camera.get(), mock_texture_id);

  ComPtr<MockCapturePreviewSink> preview_sink = new MockCapturePreviewSink();
  ComPtr<MockCaptureSource> capture_source = new MockCaptureSource();

  std::unique_ptr<uint8_t[]> mock_source_buffer =
      std::make_unique<uint8_t[]>(0);

  // Start preview to be able to start record
  MockStartPreview(capture_controller.get(), capture_source.Get(),
                   preview_sink.Get(), texture_registrar.get(), engine.Get(),
                   camera.get(), std::move(mock_source_buffer), 0, 1, 1,
                   mock_texture_id);

  // Init photo sink tests
  ComPtr<MockCapturePhotoSink> photo_sink = new MockCapturePhotoSink();
  EXPECT_CALL(*(engine.Get()), GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_PHOTO, _))
      .Times(1)
      .WillOnce(
          [src_sink = photo_sink.Get()](MF_CAPTURE_ENGINE_SINK_TYPE sink_type,
                                        IMFCaptureSink** target_sink) {
            *target_sink = src_sink;
            src_sink->AddRef();
            return S_OK;
          });
  EXPECT_CALL(*(photo_sink.Get()), RemoveAllStreams)
      .Times(1)
      .WillOnce(Return(S_OK));
  EXPECT_CALL(*(photo_sink.Get()), AddStream).Times(1).WillOnce(Return(S_OK));
  EXPECT_CALL(*(photo_sink.Get()), SetOutputFileName)
      .Times(1)
      .WillOnce(Return(S_OK));

  // Request photo
  std::string mock_path_to_photo = "mock_path_to_photo";
  EXPECT_CALL(*(engine.Get()), TakePhoto()).Times(1).WillOnce(Return(S_OK));
  capture_controller->TakePicture(mock_path_to_photo);

  // OnTakePictureSucceeded should be called with mocked file path
  EXPECT_CALL(*camera, OnTakePictureSucceeded(Eq(mock_path_to_photo))).Times(1);
  engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_PHOTO_TAKEN);

  capture_controller = nullptr;
  texture_registrar = nullptr;
  engine = nullptr;
  camera = nullptr;
  photo_sink = nullptr;
}

TEST(CaptureController, PauseResumePreviewSuccess) {
  ComPtr<MockCaptureEngine> engine = new MockCaptureEngine();
  std::unique_ptr<MockCamera> camera =
      std::make_unique<MockCamera>(MOCK_DEVICE_ID);
  std::unique_ptr<CaptureControllerImpl> capture_controller =
      std::make_unique<CaptureControllerImpl>(camera.get());
  std::unique_ptr<MockTextureRegistrar> texture_registrar =
      std::make_unique<MockTextureRegistrar>();

  uint64_t mock_texture_id = 1234;

  // Initialize capture controller to be able to start preview
  MockInitCaptureController(capture_controller.get(), texture_registrar.get(),
                            engine.Get(), camera.get(), mock_texture_id);

  ComPtr<MockCapturePreviewSink> preview_sink = new MockCapturePreviewSink();
  ComPtr<MockCaptureSource> capture_source = new MockCaptureSource();

  std::unique_ptr<uint8_t[]> mock_source_buffer =
      std::make_unique<uint8_t[]>(0);

  // Start preview to be able to start record
  MockStartPreview(capture_controller.get(), capture_source.Get(),
                   preview_sink.Get(), texture_registrar.get(), engine.Get(),
                   camera.get(), std::move(mock_source_buffer), 0, 1, 1,
                   mock_texture_id);

  EXPECT_CALL(*camera, OnPausePreviewSucceeded()).Times(1);
  capture_controller->PausePreview();

  EXPECT_CALL(*camera, OnResumePreviewSucceeded()).Times(1);
  capture_controller->ResumePreview();

  capture_controller = nullptr;
  texture_registrar = nullptr;
  engine = nullptr;
  camera = nullptr;
}

}  // namespace test
}  // namespace camera_windows
