// Copyright 2021 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 "printing/test_printing_context.h"

#include <memory>
#include <utility>

#include "base/check.h"
#include "base/containers/flat_map.h"
#include "base/notreached.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "printing/backend/print_backend.h"
#include "printing/buildflags/buildflags.h"
#include "printing/mojom/print.mojom.h"
#include "printing/print_settings.h"
#include "printing/printing_context.h"
#include "printing/units.h"
#include "ui/gfx/geometry/size.h"

#if BUILDFLAG(IS_WIN)
#include "printing/printed_page_win.h"
#endif

namespace printing {

TestPrintingContextDelegate::TestPrintingContextDelegate() = default;

TestPrintingContextDelegate::~TestPrintingContextDelegate() = default;

gfx::NativeView TestPrintingContextDelegate::GetParentView() {
  return nullptr;
}

std::string TestPrintingContextDelegate::GetAppLocale() {
  return std::string();
}

TestPrintingContext::TestPrintingContext(Delegate* delegate,
                                         bool skip_system_calls)
    : PrintingContext(delegate) {
#if BUILDFLAG(ENABLE_OOP_PRINTING)
  if (skip_system_calls)
    set_skip_system_calls();
#endif
}

TestPrintingContext::~TestPrintingContext() = default;

void TestPrintingContext::SetDeviceSettings(
    const std::string& device_name,
    std::unique_ptr<PrintSettings> settings) {
  device_settings_.emplace(device_name, std::move(settings));
}

void TestPrintingContext::AskUserForSettings(int max_pages,
                                             bool has_selection,
                                             bool is_scripted,
                                             PrintSettingsCallback callback) {
  // Do not actually ask the user with a dialog, just pretend like user
  // made some kind of interaction.
  if (ask_user_for_settings_cancel_) {
    // Pretend the user hit the Cancel button.
    std::move(callback).Run(mojom::ResultCode::kCanceled);
    return;
  }

  // Pretend the user selected the default printer and used the default
  // settings for it.
  scoped_refptr<PrintBackend> print_backend =
      PrintBackend::CreateInstance(/*locale=*/std::string());
  std::string printer_name;
  if (print_backend->GetDefaultPrinterName(printer_name) !=
      mojom::ResultCode::kSuccess) {
    std::move(callback).Run(mojom::ResultCode::kFailed);
    return;
  }
  auto found = device_settings_.find(printer_name);
  if (found == device_settings_.end()) {
    std::move(callback).Run(mojom::ResultCode::kFailed);
    return;
  }
  settings_ = std::make_unique<PrintSettings>(*found->second);
  std::move(callback).Run(mojom::ResultCode::kSuccess);
}

mojom::ResultCode TestPrintingContext::UseDefaultSettings() {
  scoped_refptr<PrintBackend> print_backend =
      PrintBackend::CreateInstance(/*locale=*/std::string());
  if (use_default_settings_fails_)
    return mojom::ResultCode::kFailed;

  std::string printer_name;
  mojom::ResultCode result = print_backend->GetDefaultPrinterName(printer_name);
  if (result != mojom::ResultCode::kSuccess)
    return result;
  auto found = device_settings_.find(printer_name);
  if (found == device_settings_.end())
    return mojom::ResultCode::kFailed;
  settings_ = std::make_unique<PrintSettings>(*found->second);
  return mojom::ResultCode::kSuccess;
}

gfx::Size TestPrintingContext::GetPdfPaperSizeDeviceUnits() {
  // Default to A4 paper size, which is an alternative to Letter size that is
  // often used as the fallback size for some platform-specific
  // implementations.
  return gfx::Size(kA4WidthInch * settings_->device_units_per_inch(),
                   kA4HeightInch * settings_->device_units_per_inch());
}

mojom::ResultCode TestPrintingContext::UpdatePrinterSettings(
    const PrinterSettings& printer_settings) {
  DCHECK(!in_print_job_);
#if BUILDFLAG(IS_MAC)
  DCHECK(!printer_settings.external_preview) << "Not implemented";
#endif
  DCHECK(!printer_settings.show_system_dialog) << "Not implemented";

  // The printer name is to be embedded in the printing context's existing
  // settings.
  const std::string& device_name = base::UTF16ToUTF8(settings_->device_name());
  auto found = device_settings_.find(device_name);
  if (found == device_settings_.end()) {
    DLOG(ERROR) << "No such device found in test printing context: `"
                << device_name << "`";
    return mojom::ResultCode::kFailed;
  }

  // Perform some initialization, akin to various platform-specific actions in
  // `InitPrintSettings()`.
  DVLOG(1) << "Updating context settings for device `" << device_name << "`";
  std::unique_ptr<PrintSettings> existing_settings = std::move(settings_);
  settings_ = std::make_unique<PrintSettings>(*found->second);
  settings_->set_dpi(existing_settings->dpi());
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  for (const auto& item : existing_settings->advanced_settings())
    settings_->advanced_settings().emplace(item.first, item.second.Clone());
#endif

  return mojom::ResultCode::kSuccess;
}

mojom::ResultCode TestPrintingContext::NewDocument(
    const std::u16string& document_name) {
  DCHECK(!in_print_job_);

  abort_printing_ = false;
  in_print_job_ = true;

  if (!skip_system_calls() && new_document_blocked_by_permissions_)
    return mojom::ResultCode::kAccessDenied;

  // No-op.
  return mojom::ResultCode::kSuccess;
}

#if BUILDFLAG(IS_WIN)
mojom::ResultCode TestPrintingContext::RenderPage(const PrintedPage& page,
                                                  const PageSetup& page_setup) {
  if (abort_printing_)
    return mojom::ResultCode::kCanceled;
  DCHECK(in_print_job_);
  DVLOG(1) << "Render page " << page.page_number();

  if (render_page_blocked_by_permissions_)
    return mojom::ResultCode::kAccessDenied;

  // No-op.
  return mojom::ResultCode::kSuccess;
}
#endif  // BUILDFLAG(IS_WIN)

mojom::ResultCode TestPrintingContext::PrintDocument(
    const MetafilePlayer& metafile,
    const PrintSettings& settings,
    uint32_t num_pages) {
  if (abort_printing_)
    return mojom::ResultCode::kCanceled;
  DCHECK(in_print_job_);
  DVLOG(1) << "Print document";

  if (render_document_blocked_by_permissions_)
    return mojom::ResultCode::kAccessDenied;

  // No-op.
  return mojom::ResultCode::kSuccess;
}

mojom::ResultCode TestPrintingContext::DocumentDone() {
  DCHECK(in_print_job_);
  DVLOG(1) << "Document done";

  if (document_done_blocked_by_permissions_)
    return mojom::ResultCode::kAccessDenied;

  ResetSettings();
  return mojom::ResultCode::kSuccess;
}

void TestPrintingContext::Cancel() {
  abort_printing_ = true;
  in_print_job_ = false;
  DVLOG(1) << "Canceling print job";
}
void TestPrintingContext::ReleaseContext() {}

printing::NativeDrawingContext TestPrintingContext::context() const {
  // No native context for test.
  return nullptr;
}

#if BUILDFLAG(IS_WIN)
mojom::ResultCode TestPrintingContext::InitWithSettingsForTest(
    std::unique_ptr<PrintSettings> settings) {
  NOTIMPLEMENTED();
  return mojom::ResultCode::kFailed;
}
#endif  // BUILDFLAG(IS_WIN)

}  // namespace printing
