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

#include "printing/printing_context_chromeos.h"

#include <cups/cups.h>
#include <stdint.h>
#include <unicode/ulocdata.h>

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

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "printing/backend/cups_connection.h"
#include "printing/backend/cups_ipp_constants.h"
#include "printing/backend/cups_ipp_helper.h"
#include "printing/backend/cups_printer.h"
#include "printing/backend/print_backend_utils.h"
#include "printing/buildflags/buildflags.h"
#include "printing/client_info_helpers.h"
#include "printing/metafile.h"
#include "printing/mojom/print.mojom.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings.h"
#include "printing/printing_utils.h"
#include "printing/units.h"

namespace printing {

namespace {

// We only support sending username for secure printers.
const char kUsernamePlaceholder[] = "chronos";

// We only support sending document name for secure printers.
const char kDocumentNamePlaceholder[] = "-";

bool IsUriSecure(base::StringPiece uri) {
  return base::StartsWith(uri, "ipps:") || base::StartsWith(uri, "https:") ||
         base::StartsWith(uri, "usb:") || base::StartsWith(uri, "ippusb:");
}

// Populates the 'client-info' attribute of the IPP collection `options`. Each
// item in `client_infos` represents one collection in 'client-info'.
// Invalid 'client-info' items will be dropped.
void EncodeClientInfo(const std::vector<mojom::IppClientInfo>& client_infos,
                      ipp_t* options) {
  std::vector<ScopedIppPtr> option_values;
  std::vector<const ipp_t*> raw_option_values;
  option_values.reserve(client_infos.size());
  raw_option_values.reserve(client_infos.size());

  for (const mojom::IppClientInfo& client_info : client_infos) {
    if (!ValidateClientInfoItem(client_info)) {
      LOG(WARNING) << "Invalid client-info item skipped";
      continue;
    }

    // Create a temporary collection object owned by this function.
    ipp_t* collection = ippNew();
    option_values.emplace_back(WrapIpp(collection));
    raw_option_values.emplace_back(collection);

    ippAddString(collection, IPP_TAG_ZERO, IPP_TAG_NAME, kIppClientName,
                 nullptr, client_info.client_name.c_str());
    ippAddInteger(collection, IPP_TAG_ZERO, IPP_TAG_ENUM, kIppClientType,
                  static_cast<int>(client_info.client_type));
    ippAddString(collection, IPP_TAG_ZERO, IPP_TAG_TEXT,
                 kIppClientStringVersion, nullptr,
                 client_info.client_string_version.c_str());

    if (client_info.client_version.has_value()) {
      ippAddOctetString(collection, IPP_TAG_ZERO, kIppClientVersion,
                        client_info.client_version.value().data(),
                        client_info.client_version.value().size());
    }

    if (client_info.client_patches.has_value()) {
      ippAddString(collection, IPP_TAG_ZERO, IPP_TAG_TEXT, kIppClientPatches,
                   nullptr, client_info.client_patches.value().c_str());
    }
  }

  if (raw_option_values.empty()) {
    return;
  }

  // Now add the client-info list to the options.
  ippAddCollections(options, IPP_TAG_OPERATION, kIppClientInfo,
                    raw_option_values.size(), raw_option_values.data());
}

// Construct the IPP media-col attribute specifying media size, margins, source,
// etc., and add it to 'options'.
void EncodeMediaCol(ipp_t* options,
                    const gfx::Size& size_um,
                    const gfx::Rect& printable_area_um,
                    bool borderless,
                    const std::string& source,
                    const std::string& type) {
  // The size and printable area in microns were calculated from the size and
  // margins in PWG units, so we can losslessly convert them back. If
  // borderless printing was requested, though, set all margins to zero.
  DCHECK_EQ(size_um.width() % kMicronsPerPwgUnit, 0);
  DCHECK_EQ(size_um.height() % kMicronsPerPwgUnit, 0);
  int width = size_um.width() / kMicronsPerPwgUnit;
  int height = size_um.height() / kMicronsPerPwgUnit;
  int bottom_margin = 0, left_margin = 0, right_margin = 0, top_margin = 0;
  if (!borderless) {
    PwgMarginsFromSizeAndPrintableArea(size_um, printable_area_um,
                                       &bottom_margin, &left_margin,
                                       &right_margin, &top_margin);
  }

  ScopedIppPtr media_col = WrapIpp(ippNew());
  ScopedIppPtr media_size = WrapIpp(ippNew());
  ippAddInteger(media_size.get(), IPP_TAG_ZERO, IPP_TAG_INTEGER, kIppXDimension,
                width);
  ippAddInteger(media_size.get(), IPP_TAG_ZERO, IPP_TAG_INTEGER, kIppYDimension,
                height);
  ippAddCollection(media_col.get(), IPP_TAG_ZERO, kIppMediaSize,
                   media_size.get());
  ippAddInteger(media_col.get(), IPP_TAG_ZERO, IPP_TAG_INTEGER,
                kIppMediaBottomMargin, bottom_margin);
  ippAddInteger(media_col.get(), IPP_TAG_ZERO, IPP_TAG_INTEGER,
                kIppMediaLeftMargin, left_margin);
  ippAddInteger(media_col.get(), IPP_TAG_ZERO, IPP_TAG_INTEGER,
                kIppMediaRightMargin, right_margin);
  ippAddInteger(media_col.get(), IPP_TAG_ZERO, IPP_TAG_INTEGER,
                kIppMediaTopMargin, top_margin);
  if (!source.empty()) {
    ippAddString(media_col.get(), IPP_TAG_ZERO, IPP_TAG_KEYWORD,
                 kIppMediaSource, nullptr, source.c_str());
  }
  if (!type.empty()) {
    ippAddString(media_col.get(), IPP_TAG_ZERO, IPP_TAG_KEYWORD, kIppMediaType,
                 nullptr, type.c_str());
  }

  ippAddCollection(options, IPP_TAG_JOB, kIppMediaCol, media_col.get());
}

std::string GetCollateString(bool collate) {
  return collate ? kCollated : kUncollated;
}

void SetPrintableArea(PrintSettings* settings,
                      const PrintSettings::RequestedMedia& media,
                      const gfx::Rect& printable_area_um) {
  if (!media.size_microns.IsEmpty()) {
    float device_microns_per_device_unit =
        static_cast<float>(kMicronsPerInch) / settings->device_units_per_inch();
    gfx::Size paper_size =
        gfx::Size(media.size_microns.width() / device_microns_per_device_unit,
                  media.size_microns.height() / device_microns_per_device_unit);

    gfx::Rect paper_rect =
        gfx::Rect(printable_area_um.x() / device_microns_per_device_unit,
                  printable_area_um.y() / device_microns_per_device_unit,
                  printable_area_um.width() / device_microns_per_device_unit,
                  printable_area_um.height() / device_microns_per_device_unit);
    settings->SetPrinterPrintableArea(paper_size, paper_rect,
                                      /*landscape_needs_flip=*/true);
  }
}

}  // namespace

ScopedIppPtr SettingsToIPPOptions(const PrintSettings& settings,
                                  const gfx::Rect& printable_area_um) {
  ScopedIppPtr scoped_options = WrapIpp(ippNew());
  ipp_t* options = scoped_options.get();

  const char* sides = nullptr;
  switch (settings.duplex_mode()) {
    case mojom::DuplexMode::kSimplex:
      sides = CUPS_SIDES_ONE_SIDED;
      break;
    case mojom::DuplexMode::kLongEdge:
      sides = CUPS_SIDES_TWO_SIDED_PORTRAIT;
      break;
    case mojom::DuplexMode::kShortEdge:
      sides = CUPS_SIDES_TWO_SIDED_LANDSCAPE;
      break;
    default:
      NOTREACHED();
  }

  // duplexing
  ippAddString(options, IPP_TAG_JOB, IPP_TAG_KEYWORD, kIppDuplex, nullptr,
               sides);
  // color
  ippAddString(options, IPP_TAG_JOB, IPP_TAG_KEYWORD, kIppColor, nullptr,
               GetIppColorModelForModel(settings.color()).c_str());
  // copies
  ippAddInteger(options, IPP_TAG_JOB, IPP_TAG_INTEGER, kIppCopies,
                settings.copies());
  // collate
  ippAddString(options, IPP_TAG_JOB, IPP_TAG_KEYWORD, kIppCollate, nullptr,
               GetCollateString(settings.collate()).c_str());

  if (!settings.pin_value().empty()) {
    ippAddOctetString(options, IPP_TAG_OPERATION, kIppPin,
                      settings.pin_value().data(), settings.pin_value().size());
    ippAddString(options, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, kIppPinEncryption,
                 nullptr, kPinEncryptionNone);
  }

  // resolution
  if (settings.dpi_horizontal() > 0 && settings.dpi_vertical() > 0) {
    ippAddResolution(options, IPP_TAG_JOB, kIppResolution, IPP_RES_PER_INCH,
                     settings.dpi_horizontal(), settings.dpi_vertical());
  }

  std::map<std::string, std::vector<int>> multival;
  std::string media_source;
  for (const auto& setting : settings.advanced_settings()) {
    const std::string& key = setting.first;
    const std::string& value = setting.second.GetString();
    if (value.empty()) {
      continue;
    }
    if (key == kIppMediaSource) {
      media_source = value;
      continue;
    }

    // Check for multivalue enum ("attribute/value").
    size_t pos = key.find('/');
    if (pos == std::string::npos) {
      // Regular value.
      ippAddString(options, IPP_TAG_JOB, IPP_TAG_KEYWORD, key.c_str(), nullptr,
                   value.c_str());
      continue;
    }
    // Store selected enum values.
    if (value == kOptionTrue) {
      std::string option_name = key.substr(0, pos);
      std::string enum_string = key.substr(pos + 1);
      int enum_value = ippEnumValue(option_name.c_str(), enum_string.c_str());
      DCHECK_NE(enum_value, -1);
      multival[option_name].push_back(enum_value);
    }
  }

  // Construct the IPP media-col attribute specifying media size, margins,
  // source, etc.
  EncodeMediaCol(options, settings.requested_media().size_microns,
                 printable_area_um, settings.borderless(), media_source,
                 settings.media_type());

  // Add multivalue enum options.
  for (const auto& it : multival) {
    ippAddIntegers(options, IPP_TAG_JOB, IPP_TAG_ENUM, it.first.c_str(),
                   it.second.size(), it.second.data());
  }

  // OAuth access token
  if (!settings.oauth_token().empty()) {
    ippAddString(options, IPP_TAG_JOB, IPP_TAG_NAME,
                 kSettingChromeOSAccessOAuthToken, nullptr,
                 settings.oauth_token().c_str());
  }

  // IPP client-info attribute.
  if (!settings.client_infos().empty()) {
    EncodeClientInfo(settings.client_infos(), options);
  }

  return scoped_options;
}

// static
std::unique_ptr<PrintingContext> PrintingContext::CreateImpl(
    Delegate* delegate,
    ProcessBehavior process_behavior) {
  return std::make_unique<PrintingContextChromeos>(delegate, process_behavior);
}

// static
std::unique_ptr<PrintingContextChromeos>
PrintingContextChromeos::CreateForTesting(
    Delegate* delegate,
    ProcessBehavior process_behavior,
    std::unique_ptr<CupsConnection> connection) {
  // Private ctor.
  return base::WrapUnique(new PrintingContextChromeos(
      delegate, process_behavior, std::move(connection)));
}

PrintingContextChromeos::PrintingContextChromeos(
    Delegate* delegate,
    ProcessBehavior process_behavior)
    : PrintingContext(delegate, process_behavior),
      connection_(CupsConnection::Create()),
      ipp_options_(WrapIpp(nullptr)) {}

PrintingContextChromeos::PrintingContextChromeos(
    Delegate* delegate,
    ProcessBehavior process_behavior,
    std::unique_ptr<CupsConnection> connection)
    : PrintingContext(delegate, process_behavior),
      connection_(std::move(connection)),
      ipp_options_(WrapIpp(nullptr)) {}

PrintingContextChromeos::~PrintingContextChromeos() {
  ReleaseContext();
}

void PrintingContextChromeos::AskUserForSettings(
    int max_pages,
    bool has_selection,
    bool is_scripted,
    PrintSettingsCallback callback) {
  // We don't want to bring up a dialog here.  Ever.  This should not be called.
  NOTREACHED();
}

mojom::ResultCode PrintingContextChromeos::UseDefaultSettings() {
  DCHECK(!in_print_job_);

  ResetSettings();

  std::string device_name = base::UTF16ToUTF8(settings_->device_name());
  if (device_name.empty())
    return OnError();

  // TODO(skau): https://crbug.com/613779. See UpdatePrinterSettings for more
  // info.
  if (settings_->dpi() == 0) {
    DVLOG(1) << "Using Default DPI";
    settings_->set_dpi(kDefaultPdfDpi);
  }

  // Retrieve device information and set it
  if (InitializeDevice(device_name) != mojom::ResultCode::kSuccess) {
    LOG(ERROR) << "Could not initialize printer";
    return OnError();
  }

  // Set printable area
  DCHECK(printer_);
  PrinterSemanticCapsAndDefaults::Paper paper = DefaultPaper(*printer_);

  PrintSettings::RequestedMedia media;
  media.vendor_id = paper.vendor_id();
  media.size_microns = paper.size_um();
  settings_->set_requested_media(media);
  SetPrintableArea(settings_.get(), media, paper.printable_area_um());

  return mojom::ResultCode::kSuccess;
}

gfx::Size PrintingContextChromeos::GetPdfPaperSizeDeviceUnits() {
  int32_t width = 0;
  int32_t height = 0;
  UErrorCode error = U_ZERO_ERROR;
  ulocdata_getPaperSize(delegate_->GetAppLocale().c_str(), &height, &width,
                        &error);
  if (error > U_ZERO_ERROR) {
    // If the call failed, assume a paper size of 8.5 x 11 inches.
    LOG(WARNING) << "ulocdata_getPaperSize failed, using 8.5 x 11, error: "
                 << error;
    width =
        static_cast<int>(kLetterWidthInch * settings_->device_units_per_inch());
    height = static_cast<int>(kLetterHeightInch *
                              settings_->device_units_per_inch());
  } else {
    // ulocdata_getPaperSize returns the width and height in mm.
    // Convert this to pixels based on the dpi.
    float multiplier = settings_->device_units_per_inch() / kMicronsPerMil;
    width *= multiplier;
    height *= multiplier;
  }
  return gfx::Size(width, height);
}

mojom::ResultCode PrintingContextChromeos::UpdatePrinterSettings(
    const PrinterSettings& printer_settings) {
  DCHECK(!printer_settings.show_system_dialog);

  if (InitializeDevice(base::UTF16ToUTF8(settings_->device_name())) !=
      mojom::ResultCode::kSuccess) {
    return OnError();
  }

  // TODO(skau): Convert to DCHECK when https://crbug.com/613779 is resolved
  // Print quality suffers when this is set to the resolution reported by the
  // printer but print quality is fine at this resolution. UseDefaultSettings
  // exhibits the same problem.
  if (settings_->dpi() == 0) {
    DVLOG(1) << "Using Default DPI";
    settings_->set_dpi(kDefaultPdfDpi);
  }

  // compute paper size
  PrintSettings::RequestedMedia media = settings_->requested_media();

  DCHECK(printer_);
  if (media.IsDefault()) {
    PrinterSemanticCapsAndDefaults::Paper paper = DefaultPaper(*printer_);

    media.vendor_id = paper.vendor_id();
    media.size_microns = paper.size_um();
    settings_->set_requested_media(media);
  }

  gfx::Rect printable_area_um =
      GetPrintableAreaForSize(*printer_, media.size_microns);
  SetPrintableArea(settings_.get(), media, printable_area_um);
  ipp_options_ = SettingsToIPPOptions(*settings_, printable_area_um);
  send_user_info_ = settings_->send_user_info();
  if (send_user_info_) {
    DCHECK(printer_);
    username_ = IsUriSecure(printer_->GetUri()) ? settings_->username()
                                                : kUsernamePlaceholder;
  }

  return mojom::ResultCode::kSuccess;
}

mojom::ResultCode PrintingContextChromeos::InitializeDevice(
    const std::string& device) {
  DCHECK(!in_print_job_);

  std::unique_ptr<CupsPrinter> printer = connection_->GetPrinter(device);
  if (!printer) {
    LOG(WARNING) << "Could not initialize device";
    return OnError();
  }

  printer_ = std::move(printer);

  return mojom::ResultCode::kSuccess;
}

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

#if BUILDFLAG(ENABLE_OOP_PRINTING)
  if (process_behavior() == ProcessBehavior::kOopEnabledSkipSystemCalls) {
    return mojom::ResultCode::kSuccess;
  }
#endif

  std::string converted_name;
  if (send_user_info_) {
    DCHECK(printer_);
    converted_name = IsUriSecure(printer_->GetUri())
                         ? base::UTF16ToUTF8(document_name)
                         : kDocumentNamePlaceholder;
  }

  ipp_status_t create_status = printer_->CreateJob(
      &job_id_, converted_name, username_, ipp_options_.get());

  if (job_id_ == 0) {
    DLOG(WARNING) << "Creating cups job failed"
                  << ippErrorString(create_status);
    return OnError();
  }

  // we only send one document, so it's always the last one
  if (!printer_->StartDocument(job_id_, converted_name, true, username_,
                               ipp_options_.get())) {
    LOG(ERROR) << "Starting document failed";
    return OnError();
  }

  return mojom::ResultCode::kSuccess;
}

mojom::ResultCode PrintingContextChromeos::PrintDocument(
    const MetafilePlayer& metafile,
    const PrintSettings& settings,
    uint32_t num_pages) {
  if (abort_printing_)
    return mojom::ResultCode::kCanceled;
  DCHECK(in_print_job_);

#if BUILDFLAG(USE_CUPS)
  std::vector<char> buffer;
  if (!metafile.GetDataAsVector(&buffer))
    return mojom::ResultCode::kFailed;

  return StreamData(buffer);
#else
  NOTREACHED();
  return mojom::ResultCode::kFailed;
#endif  // BUILDFLAG(USE_CUPS)
}

mojom::ResultCode PrintingContextChromeos::DocumentDone() {
  if (abort_printing_)
    return mojom::ResultCode::kCanceled;

  DCHECK(in_print_job_);

  if (!printer_->FinishDocument()) {
    LOG(WARNING) << "Finishing document failed";
    return OnError();
  }

  ipp_status_t job_status = printer_->CloseJob(job_id_, username_);
  job_id_ = 0;

  if (job_status != IPP_STATUS_OK) {
    LOG(WARNING) << "Closing job failed";
    return OnError();
  }

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

void PrintingContextChromeos::Cancel() {
  abort_printing_ = true;
  in_print_job_ = false;
}

void PrintingContextChromeos::ReleaseContext() {
  printer_.reset();
}

printing::NativeDrawingContext PrintingContextChromeos::context() const {
  // Intentional No-op.
  return nullptr;
}

mojom::ResultCode PrintingContextChromeos::StreamData(
    const std::vector<char>& buffer) {
  if (abort_printing_)
    return mojom::ResultCode::kCanceled;

  DCHECK(in_print_job_);
  DCHECK(printer_);

  if (!printer_->StreamData(buffer))
    return OnError();

  return mojom::ResultCode::kSuccess;
}

}  // namespace printing
