// 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 <iostream>
#include <memory>
#include <string>
#include <utility>

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/message_loop/message_pump_type.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/string_util.h>
#include <base/task/single_thread_task_executor.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <mojo/public/cpp/system/handle.h>
#include <mojo/public/cpp/system/platform_handle.h>

#include "ocr/mojo/ocr_service.mojom.h"
#include "ocr/mojo_adapter/ocr_service_mojo_adapter.h"

namespace {

namespace mojo_ipc = chromeos::ocr::mojom;

mojo::ScopedHandle GetFileHandle(const base::FilePath& path, int oflag) {
  base::ScopedFD fd(HANDLE_EINTR(open(path.value().c_str(), oflag, 0644)));

  if (fd.get() < 0) {
    PLOG(ERROR) << "Unable to open file: " << path.value();
    return mojo::ScopedHandle();
  }

  return mojo::WrapPlatformHandle(mojo::PlatformHandle(std::move(fd)));
}

mojo::ScopedHandle GetInputFileHandle(const base::FilePath& input_filepath) {
  return GetFileHandle(input_filepath,
                       O_RDONLY | O_NOFOLLOW | O_NOCTTY | O_CLOEXEC);
}

mojo::ScopedHandle GetOutputFileHandle(const base::FilePath& output_filepath) {
  return GetFileHandle(output_filepath, O_CREAT | O_WRONLY | O_CLOEXEC);
}

}  // namespace

int main(int argc, char* argv[]) {
  // Parse command line flags.
  DEFINE_string(
      input_image_filename, "",
      "Filename of input image. Supported image formats: PNG, JPEG and TIFF.");
  DEFINE_string(output_pdf_filename, "", "Filename of output PDF file.");
  DEFINE_string(language, "eng",
                "Document language. Supported languages: eng (English).");

  brillo::FlagHelper::Init(argc, argv,
                           "ocr_tool - Optical Character Recognition "
                           "command line tool.");
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);

  // When the at_exit_manager object goes out of scope, all the registered
  // callbacks and singleton destructors will be called.
  base::AtExitManager at_exit_manager;
  // Mojo requires a sequenced context.
  base::SingleThreadTaskExecutor task_executor(base::MessagePumpType::IO);

  // Get adapter instance to send requests to OCR service.
  std::unique_ptr<ocr::OcrServiceMojoAdapter> adapter =
      ocr::OcrServiceMojoAdapter::Create();
  DCHECK(adapter);

  // Validate input arguments.
  base::FilePath input_image_filename =
      base::FilePath(FLAGS_input_image_filename);
  if (input_image_filename.empty()) {
    LOG(ERROR) << "--input_image_filename must be specified."
                  " Use --help for help on usage.";
    return EXIT_FAILURE;
  }

  base::FilePath output_pdf_filename =
      base::FilePath(FLAGS_output_pdf_filename);
  if (output_pdf_filename.empty())
    output_pdf_filename = input_image_filename.ReplaceExtension("pdf");

  if (!base::EqualsCaseInsensitiveASCII(output_pdf_filename.Extension(),
                                        ".pdf")) {
    LOG(ERROR) << "--output_pdf_filename must have a .pdf extension."
                  " Use --help for help on usage.";
    return EXIT_FAILURE;
  }

  if (FLAGS_language.compare("eng") != 0) {
    LOG(ERROR) << "Selected language " << FLAGS_language
               << " is not supported."
                  " Use --help for help on usage.";
    return EXIT_FAILURE;
  }

  // Construct request.
  mojo::ScopedHandle input_fd_handle = GetInputFileHandle(input_image_filename);
  if (!input_fd_handle)
    return EXIT_FAILURE;

  mojo::ScopedHandle output_fd_handle =
      GetOutputFileHandle(output_pdf_filename);
  if (!output_fd_handle)
    return EXIT_FAILURE;

  mojo_ipc::OcrConfigPtr ocr_config = mojo_ipc::OcrConfig::New();
  ocr_config->language = FLAGS_language;
  mojo_ipc::PdfRendererConfigPtr pdf_renderer_config =
      mojo_ipc::PdfRendererConfig::New();

  // Perform OCR.
  auto response = adapter->GenerateSearchablePdfFromImage(
      std::move(input_fd_handle), std::move(output_fd_handle),
      std::move(ocr_config), std::move(pdf_renderer_config));

  if (!response) {
    LOG(ERROR) << "No response received from GenerateSearchablePdfFromImage().";
    return EXIT_FAILURE;
  }

  bool success = response->result == mojo_ipc::OcrResultEnum::SUCCESS;
  if (success) {
    std::cout << "Generated searchable PDF file: " << output_pdf_filename
              << std::endl;
  } else {
    LOG(ERROR) << response->result_message;
  }

  return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
