// 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,
                    const std::string& source) {
  // The size and printable area in microns were calculated from the size and
  // margins in PWG units, so we can losslessly convert them back.
  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;
  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());
  }

  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, media_source);

  // 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,
    bool skip_system_calls) {
  auto context = std::make_unique<PrintingContextChromeos>(delegate);
#if BUILDFLAG(ENABLE_OOP_PRINTING)
  if (skip_system_calls)
    context->set_skip_system_calls();
#endif
  return context;
}

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

PrintingContextChromeos::PrintingContextChromeos(Delegate* delegate)
    : PrintingContext(delegate),
      connection_(CupsConnection::Create(GURL(), HTTP_ENCRYPT_NEVER, true)),
      ipp_options_(WrapIpp(nullptr)) {}

PrintingContextChromeos::PrintingContextChromeos(
    Delegate* delegate,
    std::unique_ptr<CupsConnection> connection)
    : PrintingContext(delegate),
      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 (skip_system_calls())
    return mojom::ResultCode::kSuccess;

  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
