// Copyright 2020 The Chromium OS 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 <fcntl.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/message_loop/message_pump_type.h>
#include <base/posix/eintr_wrapper.h>
#include <base/run_loop.h>
#include <base/task/single_thread_task_executor.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mojo/core/embedder/embedder.h>
#include <mojo/public/cpp/system/handle.h>
#include <mojo/public/cpp/bindings/pending_receiver.h>
#include <mojo/public/cpp/system/platform_handle.h>
#include <mojo/public/cpp/bindings/remote.h>

#include "ocr/mojo/ocr_service.mojom.h"
#include "ocr/ocr_service_impl.h"

namespace ocr {

namespace {

namespace mojo_ipc = chromeos::ocr::mojom;

// The relative path of the input test image.
constexpr char kTestImageRelativePath[] = "./test_images/phototest.tif";
// The name of the output pdf file.
constexpr char kOutputPdfFilename[] = "phototest.pdf";

mojo::ScopedHandle GetInputFileHandle(const std::string& input_filename) {
  base::ScopedFD input_fd(HANDLE_EINTR(
      open(input_filename.c_str(), O_RDONLY | O_NOFOLLOW | O_NOCTTY)));
  return mojo::WrapPlatformHandle(mojo::PlatformHandle(std::move(input_fd)));
}

mojo::ScopedHandle GetOutputFileHandle(const std::string& output_filename) {
  base::ScopedFD out_fd(
      HANDLE_EINTR(open(output_filename.c_str(), O_CREAT | O_WRONLY, 0644)));
  return mojo::WrapPlatformHandle(mojo::PlatformHandle(std::move(out_fd)));
}

}  // namespace

class OcrServiceImplTest : public testing::Test {
 protected:
  OcrServiceImplTest() { mojo::core::Init(); }

  void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }

  OcrServiceImpl* ocr_service() { return &ocr_service_impl_; }
  const base::FilePath& temp_dir_path() const { return temp_dir_.GetPath(); }

 private:
  OcrServiceImpl ocr_service_impl_;
  base::SingleThreadTaskExecutor executor_{base::MessagePumpType::IO};
  base::ScopedTempDir temp_dir_;
};

// Tests OCR on a valid input image and with valid parameters.
TEST_F(OcrServiceImplTest, GenerateSearchablePdfFromImageSuccess) {
  mojo::Remote<mojo_ipc::OpticalCharacterRecognitionService> remote;
  EXPECT_FALSE(remote);
  ocr_service()->AddReceiver(remote.BindNewPipeAndPassReceiver(),
                             false /* should_quit */);
  ASSERT_TRUE(remote);

  // Construct request.
  const std::string input_image_filename =
      base::FilePath(kTestImageRelativePath).value();
  mojo::ScopedHandle input_fd_handle = GetInputFileHandle(input_image_filename);
  const std::string output_filename =
      temp_dir_path().Append(kOutputPdfFilename).value();
  mojo::ScopedHandle output_fd_handle = GetOutputFileHandle(output_filename);
  mojo_ipc::OcrConfigPtr ocr_config = mojo_ipc::OcrConfig::New();
  mojo_ipc::PdfRendererConfigPtr pdf_renderer_config =
      mojo_ipc::PdfRendererConfig::New();

  // Perform OCR.
  bool ocr_callback_done = false;
  // Ensure that remote is bound.
  remote->GenerateSearchablePdfFromImage(
      std::move(input_fd_handle), std::move(output_fd_handle),
      std::move(ocr_config), std::move(pdf_renderer_config),
      base::BindOnce(
          [](bool* ocr_callback_done,
             const mojo_ipc::OpticalCharacterRecognitionServiceResponsePtr
                 response) {
            EXPECT_EQ(response->result, mojo_ipc::OcrResultEnum::SUCCESS);
            *ocr_callback_done = true;
          },
          &ocr_callback_done));
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(ocr_callback_done);
}

TEST_F(OcrServiceImplTest, OcrFailToLoadLanguage) {
  // Construct request.
  const std::string input_image_filename =
      base::FilePath(kTestImageRelativePath).value();
  mojo::ScopedHandle input_fd_handle = GetInputFileHandle(input_image_filename);
  const std::string output_filename =
      temp_dir_path().Append(kOutputPdfFilename).value();
  mojo::ScopedHandle output_fd_handle = GetOutputFileHandle(output_filename);
  mojo_ipc::OcrConfigPtr ocr_config = mojo_ipc::OcrConfig::New();
  ocr_config->language = "deu";
  mojo_ipc::PdfRendererConfigPtr pdf_renderer_config =
      mojo_ipc::PdfRendererConfig::New();

  // Perform OCR.
  bool ocr_callback_done = false;
  // Ensure that remote is bound.
  ocr_service()->GenerateSearchablePdfFromImage(
      std::move(input_fd_handle), std::move(output_fd_handle),
      std::move(ocr_config), std::move(pdf_renderer_config),
      base::BindOnce(
          [](bool* ocr_callback_done,
             const mojo_ipc::OpticalCharacterRecognitionServiceResponsePtr
                 response) {
            EXPECT_EQ(response->result,
                      mojo_ipc::OcrResultEnum::LANGUAGE_NOT_SUPPORTED_ERROR);
            *ocr_callback_done = true;
          },
          &ocr_callback_done));
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(ocr_callback_done);
}

TEST_F(OcrServiceImplTest, OcrInvalidInputImageFileHandle) {
  // Construct request.
  mojo::ScopedHandle input_fd_handle = mojo::ScopedHandle();
  const std::string output_filename =
      temp_dir_path().Append(kOutputPdfFilename).value();
  mojo::ScopedHandle output_fd_handle = GetOutputFileHandle(output_filename);
  mojo_ipc::OcrConfigPtr ocr_config = mojo_ipc::OcrConfig::New();
  mojo_ipc::PdfRendererConfigPtr pdf_renderer_config =
      mojo_ipc::PdfRendererConfig::New();

  // Perform OCR.
  bool ocr_callback_done = false;
  // Ensure that remote is bound.
  ocr_service()->GenerateSearchablePdfFromImage(
      std::move(input_fd_handle), std::move(output_fd_handle),
      std::move(ocr_config), std::move(pdf_renderer_config),
      base::BindOnce(
          [](bool* ocr_callback_done,
             const mojo_ipc::OpticalCharacterRecognitionServiceResponsePtr
                 response) {
            EXPECT_EQ(response->result,
                      mojo_ipc::OcrResultEnum::INPUT_FILE_ERROR);
            *ocr_callback_done = true;
          },
          &ocr_callback_done));
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(ocr_callback_done);
}

TEST_F(OcrServiceImplTest, OcrInvalidOutputPdfFileHandle) {
  // Construct request.
  const std::string input_image_filename =
      base::FilePath(kTestImageRelativePath).value();
  mojo::ScopedHandle input_fd_handle = GetInputFileHandle(input_image_filename);
  mojo::ScopedHandle output_fd_handle = mojo::ScopedHandle();
  mojo_ipc::OcrConfigPtr ocr_config = mojo_ipc::OcrConfig::New();
  mojo_ipc::PdfRendererConfigPtr pdf_renderer_config =
      mojo_ipc::PdfRendererConfig::New();

  // Perform OCR.
  bool ocr_callback_done = false;
  // Ensure that remote is bound.
  ocr_service()->GenerateSearchablePdfFromImage(
      std::move(input_fd_handle), std::move(output_fd_handle),
      std::move(ocr_config), std::move(pdf_renderer_config),
      base::BindOnce(
          [](bool* ocr_callback_done,
             const mojo_ipc::OpticalCharacterRecognitionServiceResponsePtr
                 response) {
            EXPECT_EQ(response->result,
                      mojo_ipc::OcrResultEnum::OUTPUT_FILE_ERROR);
            *ocr_callback_done = true;
          },
          &ocr_callback_done));
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(ocr_callback_done);
}

}  // namespace ocr
