// 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/backend/cups_ipp_helper.h"

#include <cups/cups.h>

#include <algorithm>
#include <map>
#include <string>
#include <vector>

#include "base/containers/contains.h"
#include "base/containers/fixed_flat_set.h"
#include "base/containers/flat_map.h"
#include "base/logging.h"
#include "base/numerics/clamped_math.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "printing/backend/cups_connection.h"
#include "printing/backend/cups_ipp_constants.h"
#include "printing/backend/cups_printer.h"
#include "printing/backend/print_backend_consts.h"
#include "printing/backend/print_backend_utils.h"
#include "printing/mojom/print.mojom.h"
#include "printing/printing_utils.h"
#include "printing/units.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "base/functional/callback.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "printing/backend/ipp_handler_map.h"
#include "printing/backend/ipp_handlers.h"
#include "printing/printing_features.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace printing {

#if BUILDFLAG(IS_CHROMEOS)
constexpr int kPinMinimumLength = 4;
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace {

constexpr double kMMPerInch = 25.4;
constexpr double kCmPerInch = kMMPerInch * 0.1;

struct ColorMap {
  const char* color;
  mojom::ColorModel model;
};

struct DuplexMap {
  const char* name;
  mojom::DuplexMode mode;
};

const ColorMap kColorList[]{
    {CUPS_PRINT_COLOR_MODE_COLOR, mojom::ColorModel::kColorModeColor},
    {CUPS_PRINT_COLOR_MODE_MONOCHROME, mojom::ColorModel::kColorModeMonochrome},
};

const DuplexMap kDuplexList[]{
    {CUPS_SIDES_ONE_SIDED, mojom::DuplexMode::kSimplex},
    {CUPS_SIDES_TWO_SIDED_PORTRAIT, mojom::DuplexMode::kLongEdge},
    {CUPS_SIDES_TWO_SIDED_LANDSCAPE, mojom::DuplexMode::kShortEdge},
};

mojom::ColorModel ColorModelFromIppColor(base::StringPiece ippColor) {
  for (const ColorMap& color : kColorList) {
    if (ippColor.compare(color.color) == 0) {
      return color.model;
    }
  }

  return mojom::ColorModel::kUnknownColorModel;
}

mojom::DuplexMode DuplexModeFromIpp(base::StringPiece ipp_duplex) {
  for (const DuplexMap& entry : kDuplexList) {
    if (base::EqualsCaseInsensitiveASCII(ipp_duplex, entry.name))
      return entry.mode;
  }
  return mojom::DuplexMode::kUnknownDuplexMode;
}

mojom::ColorModel DefaultColorModel(const CupsOptionProvider& printer) {
  // default color
  ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppColor);
  if (!attr)
    return mojom::ColorModel::kUnknownColorModel;

  const char* const value = ippGetString(attr, 0, nullptr);
  return value ? ColorModelFromIppColor(value)
               : mojom::ColorModel::kUnknownColorModel;
}

std::vector<mojom::ColorModel> SupportedColorModels(
    const CupsOptionProvider& printer) {
  std::vector<mojom::ColorModel> colors;

  std::vector<base::StringPiece> color_modes =
      printer.GetSupportedOptionValueStrings(kIppColor);
  for (base::StringPiece color : color_modes) {
    mojom::ColorModel color_model = ColorModelFromIppColor(color);
    if (color_model != mojom::ColorModel::kUnknownColorModel) {
      colors.push_back(color_model);
    }
  }

  return colors;
}

void ExtractColor(const CupsOptionProvider& printer,
                  PrinterSemanticCapsAndDefaults* printer_info) {
  printer_info->bw_model = mojom::ColorModel::kUnknownColorModel;
  printer_info->color_model = mojom::ColorModel::kUnknownColorModel;

  // color and b&w
  std::vector<mojom::ColorModel> color_models = SupportedColorModels(printer);
  for (mojom::ColorModel color : color_models) {
    switch (color) {
      case mojom::ColorModel::kColorModeColor:
        printer_info->color_model = mojom::ColorModel::kColorModeColor;
        break;
      case mojom::ColorModel::kColorModeMonochrome:
        printer_info->bw_model = mojom::ColorModel::kColorModeMonochrome;
        break;
      default:
        // value not needed
        break;
    }
  }

  // changeable
  printer_info->color_changeable =
      (printer_info->color_model != mojom::ColorModel::kUnknownColorModel &&
       printer_info->bw_model != mojom::ColorModel::kUnknownColorModel);

  // default color
  printer_info->color_default =
      DefaultColorModel(printer) == mojom::ColorModel::kColorModeColor;
}

void ExtractDuplexModes(const CupsOptionProvider& printer,
                        PrinterSemanticCapsAndDefaults* printer_info) {
  std::vector<base::StringPiece> duplex_modes =
      printer.GetSupportedOptionValueStrings(kIppDuplex);
  for (base::StringPiece duplex : duplex_modes) {
    mojom::DuplexMode duplex_mode = DuplexModeFromIpp(duplex);
    if (duplex_mode != mojom::DuplexMode::kUnknownDuplexMode)
      printer_info->duplex_modes.push_back(duplex_mode);
  }

  ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppDuplex);
  if (!attr) {
    printer_info->duplex_default = mojom::DuplexMode::kUnknownDuplexMode;
    return;
  }

  const char* const attr_str = ippGetString(attr, 0, nullptr);
  printer_info->duplex_default = attr_str
                                     ? DuplexModeFromIpp(attr_str)
                                     : mojom::DuplexMode::kUnknownDuplexMode;
}

void CopiesRange(const CupsOptionProvider& printer,
                 int* lower_bound,
                 int* upper_bound) {
  ipp_attribute_t* attr = printer.GetSupportedOptionValues(kIppCopies);
  if (!attr) {
    *lower_bound = -1;
    *upper_bound = -1;
  }

  *lower_bound = ippGetRange(attr, 0, upper_bound);
}

void ExtractCopies(const CupsOptionProvider& printer,
                   PrinterSemanticCapsAndDefaults* printer_info) {
  // copies
  int lower_bound;
  int upper_bound;
  CopiesRange(printer, &lower_bound, &upper_bound);
  printer_info->copies_max =
      (lower_bound != -1 && upper_bound >= 2) ? upper_bound : 1;
}

// Reads resolution from `attr` and puts into `size` in dots per inch.
absl::optional<gfx::Size> GetResolution(ipp_attribute_t* attr, int i) {
  ipp_res_t units;
  int yres;
  int xres = ippGetResolution(attr, i, &yres, &units);
  if (!xres)
    return {};

  switch (units) {
    case IPP_RES_PER_INCH:
      return gfx::Size(xres, yres);
    case IPP_RES_PER_CM:
      return gfx::Size(xres * kCmPerInch, yres * kCmPerInch);
  }
  return {};
}

// Initializes `printer_info.dpis` with available resolutions and
// `printer_info.default_dpi` with default resolution provided by `printer`.
void ExtractResolutions(const CupsOptionProvider& printer,
                        PrinterSemanticCapsAndDefaults* printer_info) {
  // Provide a default DPI if no valid DPI is found.
#if BUILDFLAG(IS_MAC)
  constexpr gfx::Size kDefaultMissingDpi(kDefaultMacDpi, kDefaultMacDpi);
#elif BUILDFLAG(IS_LINUX)
  constexpr gfx::Size kDefaultMissingDpi(kPixelsPerInch, kPixelsPerInch);
#else
  constexpr gfx::Size kDefaultMissingDpi(kDefaultPdfDpi, kDefaultPdfDpi);
#endif

  ipp_attribute_t* attr = printer.GetSupportedOptionValues(kIppResolution);
  if (!attr) {
    printer_info->dpis.push_back(kDefaultMissingDpi);
    return;
  }

  int num_options = ippGetCount(attr);
  for (int i = 0; i < num_options; i++) {
    absl::optional<gfx::Size> size = GetResolution(attr, i);
    if (size)
      printer_info->dpis.push_back(size.value());
  }
  ipp_attribute_t* def_attr = printer.GetDefaultOptionValue(kIppResolution);
  absl::optional<gfx::Size> size = GetResolution(def_attr, 0);
  if (size) {
    printer_info->default_dpi = size.value();
  } else if (!printer_info->dpis.empty()) {
    printer_info->default_dpi = printer_info->dpis[0];
  } else {
    printer_info->default_dpi = kDefaultMissingDpi;
  }

  if (printer_info->dpis.empty()) {
    printer_info->dpis.push_back(printer_info->default_dpi);
  }
}

absl::optional<PrinterSemanticCapsAndDefaults::Paper>
PaperFromMediaColDatabaseEntry(ipp_t* db_entry) {
  DCHECK(db_entry);

  absl::optional<MediaColData> size = ExtractMediaColData(db_entry);
  if (!size) {
    LOG(WARNING) << "Unable to create Paper from media-col-database";
    return absl::nullopt;
  }

  if (size->HasVariableWidth()) {
    LOG(WARNING) << "Invalid media-col-database entry:"
                 << " variable widths are not supported.";
    return absl::nullopt;
  }

  // Some PPDs (only ones with a custom height range) have a min height of 0,
  // which doesn't work with the printing stack.  If there is a min height of 0
  // (or equal to the margins) change it to some small value.  For entries that
  // have a fixed height, the height will not get modified; if this fixed height
  // is invalid, it will just get rejected below.
  if (size->HasVariableHeight()) {
    size->min_height = base::ClampMax(
        size->min_height,
        base::ClampedNumeric<int>(size->top_margin) + size->bottom_margin + 1);
  }

  if (size->min_width <= 0 || size->min_height <= 0 ||
      size->bottom_margin < 0 || size->top_margin < 0 ||
      size->left_margin < 0 || size->right_margin < 0 ||
      size->min_width <=
          base::ClampedNumeric<int>(size->left_margin) + size->right_margin ||
      size->min_height <=
          base::ClampedNumeric<int>(size->bottom_margin) + size->top_margin ||
      (size->HasVariableHeight() && size->max_height < size->min_height)) {
    LOG(WARNING) << "Invalid media-col-database entry:"
                 << " width=" << size->min_width << "-" << size->max_width
                 << " height=" << size->min_height << "-" << size->max_height
                 << " media-bottom-margin=" << size->bottom_margin
                 << " media-left-margin=" << size->left_margin
                 << " media-right-margin=" << size->right_margin
                 << " media-top-margin=" << size->top_margin;
    return absl::nullopt;
  }

  gfx::Size size_um(size->min_width * kMicronsPerPwgUnit,
                    size->min_height * kMicronsPerPwgUnit);
  gfx::Rect printable_area_um = PrintableAreaFromSizeAndPwgMargins(
      size_um, size->bottom_margin, size->left_margin, size->right_margin,
      size->top_margin);
  int max_height_um =
      size->HasVariableHeight() ? size->max_height * kMicronsPerPwgUnit : 0;

  return PrinterSemanticCapsAndDefaults::Paper(
      /*display_name=*/"", /*vendor_id=*/"", size_um, printable_area_um,
      max_height_um);
}

bool PaperIsBorderless(const PrinterSemanticCapsAndDefaults::Paper& paper) {
  return paper.printable_area_um().x() == 0 &&
         paper.printable_area_um().y() == 0 &&
         paper.printable_area_um().width() == paper.size_um().width() &&
         paper.printable_area_um().height() == paper.size_um().height();
}

PrinterSemanticCapsAndDefaults::Papers SupportedPapers(
    const CupsPrinter& printer) {
  auto size_comparer = [](const gfx::Size& a, const gfx::Size& b) {
    auto result = a.width() - b.width();
    if (result == 0) {
      result = a.height() - b.height();
    }
    return result < 0;
  };
  std::map<gfx::Size, PrinterSemanticCapsAndDefaults::Paper,
           decltype(size_comparer)>
      paper_map;

  ipp_attribute_t* attr = printer.GetMediaColDatabase();
  int count = ippGetCount(attr);

  for (int i = 0; i < count; i++) {
    absl::optional<PrinterSemanticCapsAndDefaults::Paper> paper_opt =
        PaperFromMediaColDatabaseEntry(ippGetCollection(attr, i));
    if (!paper_opt.has_value()) {
      continue;
    }

    const auto& paper = paper_opt.value();
    auto existing_entry = paper_map.find(paper.size_um());

    if (existing_entry == paper_map.end()) {
      paper_map.emplace(paper.size_um(), paper);
      continue;
    }

    // When a paper size has both bordered and borderless variants, set the
    // printable area according to the bordered variant, and set the flag
    // indicating that a borderless variant exists.
    if (PaperIsBorderless(existing_entry->second)) {
      if (!PaperIsBorderless(paper)) {
        existing_entry->second = paper;
        existing_entry->second.set_has_borderless_variant(true);
      }
    } else if (PaperIsBorderless(paper)) {
      existing_entry->second.set_has_borderless_variant(true);
    }
  }

  PrinterSemanticCapsAndDefaults::Papers parsed_papers;
  parsed_papers.reserve(paper_map.size());
  for (const auto& entry : paper_map) {
    parsed_papers.push_back(entry.second);
  }
  return parsed_papers;
}

// Initializes `printer_info->media_types` with available media types and
// `printer_info->default_media_type` with default media type provided by
// `printer`.
void ExtractMediaTypes(const CupsOptionProvider& printer,
                       PrinterSemanticCapsAndDefaults* printer_info) {
  std::vector<base::StringPiece> names =
      printer.GetSupportedOptionValueStrings(kIppMediaType);
  if (names.empty()) {
    return;
  }
  printer_info->media_types.reserve(names.size());

  for (base::StringPiece vendor_id : names) {
    PrinterSemanticCapsAndDefaults::MediaType type;
    type.vendor_id = std::string(vendor_id);

    // This name will be overwritten by its Chromium localization if it's a
    // standard IPP media type. But for non-standard types, the only
    // human-readable name available is this one from the driver (or
    // driverless printer).
    const char* display_name = printer.GetLocalizedOptionValueName(
        kIppMediaType, type.vendor_id.c_str());
    if (display_name) {
      type.display_name = display_name;
    } else {
      type.display_name = std::string(vendor_id);
    }

    printer_info->media_types.push_back(type);
  }

  // Set default media type, or use the first in the list if unavailable.
  DCHECK(!printer_info->media_types.empty());
  printer_info->default_media_type = printer_info->media_types[0];
  ipp_t* media_col_default =
      ippGetCollection(printer.GetDefaultOptionValue(kIppMediaCol), 0);
  const char* media_type_default = ippGetString(
      ippFindAttribute(media_col_default, "media-type", IPP_TAG_KEYWORD), 0,
      nullptr);
  if (media_type_default) {
    // Don't set the "default" media type if it isn't in the list of supported
    // media types for some reason.
    for (const auto& media_type : printer_info->media_types) {
      if (media_type.vendor_id == media_type_default) {
        printer_info->default_media_type = media_type;
      }
    }
  }
}

bool CollateCapable(const CupsOptionProvider& printer) {
  std::vector<base::StringPiece> values =
      printer.GetSupportedOptionValueStrings(kIppCollate);
  return base::Contains(values, kCollated) &&
         base::Contains(values, kUncollated);
}

bool CollateDefault(const CupsOptionProvider& printer) {
  ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppCollate);
  if (!attr)
    return false;

  const char* const name = ippGetString(attr, 0, nullptr);
  return name && !base::StringPiece(name).compare(kCollated);
}

#if BUILDFLAG(IS_CHROMEOS)
bool PinSupported(const CupsOptionProvider& printer) {
  ipp_attribute_t* attr = printer.GetSupportedOptionValues(kIppPin);
  if (!attr)
    return false;
  int password_maximum_length_supported = ippGetInteger(attr, 0);
  if (password_maximum_length_supported < kPinMinimumLength)
    return false;

  std::vector<base::StringPiece> values =
      printer.GetSupportedOptionValueStrings(kIppPinEncryption);
  return base::Contains(values, kPinEncryptionNone);
}

// Returns the number of IPP attributes added to `caps` (not necessarily in
// 1-to-1 correspondence).
size_t AddAttributes(const CupsOptionProvider& printer,
                     const char* attr_group_name,
                     AdvancedCapabilities* caps) {
  ipp_attribute_t* attr = printer.GetSupportedOptionValues(attr_group_name);
  if (!attr)
    return 0;

  int num_options = ippGetCount(attr);
  static const base::NoDestructor<HandlerMap> handlers(GenerateHandlers());
  // The names of attributes that we know are not supported (b/266573545).
  static constexpr auto kOptionsToIgnore =
      base::MakeFixedFlatSet<base::StringPiece>(
          {"finishings-col", "ipp-attribute-fidelity", "job-name",
           "number-up-layout"});
  std::vector<std::string> unknown_options;
  size_t attr_count = 0;
  for (int i = 0; i < num_options; i++) {
    const char* option_name = ippGetString(attr, i, nullptr);
    if (base::Contains(kOptionsToIgnore, option_name)) {
      continue;
    }
    auto it = handlers->find(option_name);
    if (it == handlers->end()) {
      unknown_options.emplace_back(option_name);
      continue;
    }

    size_t previous_size = caps->size();
    // Run the handler that adds items to `caps` based on option type.
    it->second.Run(printer, option_name, caps);
    if (caps->size() > previous_size)
      attr_count++;
  }
  if (!unknown_options.empty()) {
    LOG(WARNING) << "Unknown IPP options: "
                 << base::JoinString(unknown_options, ", ");
  }
  return attr_count;
}

// Adds the "Input Tray" option to Advanced Attributes.
size_t AddInputTray(const CupsOptionProvider& printer,
                    AdvancedCapabilities* caps) {
  size_t previous_size = caps->size();
  KeywordHandler(printer, "media-source", caps);
  return caps->size() - previous_size;
}

void ExtractAdvancedCapabilities(const CupsOptionProvider& printer,
                                 PrinterSemanticCapsAndDefaults* printer_info) {
  AdvancedCapabilities* options = &printer_info->advanced_capabilities;
  size_t attr_count = AddInputTray(printer, options);
  attr_count += AddAttributes(printer, kIppJobAttributes, options);
  attr_count += AddAttributes(printer, kIppDocumentAttributes, options);
  base::UmaHistogramCounts1000("Printing.CUPS.IppAttributesCount", attr_count);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace

PrinterSemanticCapsAndDefaults::Paper DefaultPaper(const CupsPrinter& printer) {
  ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppMediaCol);
  if (!attr)
    return PrinterSemanticCapsAndDefaults::Paper();
  ipp_t* media_col_default = ippGetCollection(attr, 0);
  if (!media_col_default) {
    return PrinterSemanticCapsAndDefaults::Paper();
  }

  PrinterSemanticCapsAndDefaults::Paper paper;
  return PaperFromMediaColDatabaseEntry(media_col_default)
      .value_or(PrinterSemanticCapsAndDefaults::Paper());
}

void CapsAndDefaultsFromPrinter(const CupsPrinter& printer,
                                PrinterSemanticCapsAndDefaults* printer_info) {
  // collate
  printer_info->collate_default = CollateDefault(printer);
  printer_info->collate_capable = CollateCapable(printer);

  // paper
  printer_info->default_paper = DefaultPaper(printer);
  printer_info->papers = SupportedPapers(printer);

#if BUILDFLAG(IS_CHROMEOS)
  printer_info->pin_supported = PinSupported(printer);
  ExtractAdvancedCapabilities(printer, printer_info);
#endif  // BUILDFLAG(IS_CHROMEOS)

  ExtractCopies(printer, printer_info);
  ExtractColor(printer, printer_info);
  ExtractDuplexModes(printer, printer_info);
  ExtractResolutions(printer, printer_info);
  ExtractMediaTypes(printer, printer_info);
}

gfx::Rect GetPrintableAreaForSize(const CupsPrinter& printer,
                                  const gfx::Size& size_um) {
  ipp_attribute_t* attr = printer.GetMediaColDatabase();
  int count = ippGetCount(attr);
  gfx::Rect result(0, 0, size_um.width(), size_um.height());

  for (int i = 0; i < count; i++) {
    ipp_t* db_entry = ippGetCollection(attr, i);

    absl::optional<PrinterSemanticCapsAndDefaults::Paper> paper_opt =
        PaperFromMediaColDatabaseEntry(db_entry);
    if (!paper_opt.has_value()) {
      continue;
    }

    const auto& paper = paper_opt.value();
    if (paper.size_um() != size_um) {
      continue;
    }

    result = paper.printable_area_um();

    // If this is a borderless size, try to find a non-borderless version.
    if (!PaperIsBorderless(paper)) {
      return result;
    }
  }

  return result;
}

ScopedIppPtr WrapIpp(ipp_t* ipp) {
  return ScopedIppPtr(ipp, IppDeleter());
}

void IppDeleter::operator()(ipp_t* ipp) const {
  ippDelete(ipp);
}

absl::optional<MediaColData> ExtractMediaColData(ipp_t* db_entry) {
  if (!db_entry) {
    LOG(WARNING) << "Invalid media-col-database entry: empty entry.";
    return absl::nullopt;
  }
  ipp_t* media_size = ippGetCollection(
      ippFindAttribute(db_entry, kIppMediaSize, IPP_TAG_BEGIN_COLLECTION), 0);
  if (!media_size) {
    LOG(WARNING) << "Invalid media-col-database entry: empty media_size.";
    return absl::nullopt;
  }

  ipp_attribute_t* bottom_attr =
      ippFindAttribute(db_entry, kIppMediaBottomMargin, IPP_TAG_INTEGER);
  ipp_attribute_t* left_attr =
      ippFindAttribute(db_entry, kIppMediaLeftMargin, IPP_TAG_INTEGER);
  ipp_attribute_t* right_attr =
      ippFindAttribute(db_entry, kIppMediaRightMargin, IPP_TAG_INTEGER);
  ipp_attribute_t* top_attr =
      ippFindAttribute(db_entry, kIppMediaTopMargin, IPP_TAG_INTEGER);
  if (!bottom_attr || !left_attr || !right_attr || !top_attr) {
    LOG(WARNING) << "Invalid media-col-database entry:"
                 << " margins are not present.";
    return absl::nullopt;
  }
  int bottom_margin = ippGetInteger(bottom_attr, 0);
  int left_margin = ippGetInteger(left_attr, 0);
  int right_margin = ippGetInteger(right_attr, 0);
  int top_margin = ippGetInteger(top_attr, 0);

  ipp_attribute_t* width_attr =
      ippFindAttribute(media_size, kIppXDimension, IPP_TAG_INTEGER);
  ipp_attribute_t* height_attr =
      ippFindAttribute(media_size, kIppYDimension, IPP_TAG_INTEGER);
  ipp_attribute_t* width_range_attr =
      ippFindAttribute(media_size, kIppXDimension, IPP_TAG_RANGE);
  ipp_attribute_t* height_range_attr =
      ippFindAttribute(media_size, kIppYDimension, IPP_TAG_RANGE);

  // Ensure there is a width and height (or ranges).
  if ((!width_attr && !width_range_attr) ||
      (!height_attr && !height_range_attr)) {
    LOG(WARNING) << "Invalid media-col-database entry:"
                 << " media-size needs x and y (or x and y range).";
    return absl::nullopt;
  }

  int min_width = 0;
  int min_height = 0;
  int max_width = 0;
  int max_height = 0;
  if (width_attr) {
    min_width = ippGetInteger(width_attr, 0);
    max_width = min_width;
  } else {
    min_width = ippGetRange(width_range_attr, 0, &max_width);
  }
  if (height_attr) {
    min_height = ippGetInteger(height_attr, 0);
    max_height = min_height;
  } else {
    min_height = ippGetRange(height_range_attr, 0, &max_height);
  }

  if (min_width > max_width) {
    LOG(WARNING) << "Invalid media-col-database entry:"
                 << " min_width (" << min_width << ") > max_width ("
                 << max_width << ").";
    return absl::nullopt;
  }
  if (min_height > max_height) {
    LOG(WARNING) << "Invalid media-col-database entry:"
                 << " min_height (" << min_height << ") > max_height ("
                 << max_height << ").";
    return absl::nullopt;
  }

#if BUILDFLAG(IS_MAC)
  pwg_media_t* media = pwgMediaForSize(max_width, max_height);
  if (media && (media->width != max_width || media->length != max_height)) {
    // Paper size detected to be close to a standard size.  While the maximum
    // size will be based on this media, must also do checks to adjust the
    // minimum dimensions, as they must not end up exceeding the new maximum.
    if (min_width == max_width || min_width > media->width) {
      min_width = media->width;
    }
    if (min_height == max_height || min_height > media->length) {
      min_height = media->length;
    }
    max_width = media->width;
    max_height = media->length;
  }
#endif

  return MediaColData{min_width,     min_height,  max_width,    max_height,
                      bottom_margin, left_margin, right_margin, top_margin};
}

ScopedIppPtr NewMediaCollection(const MediaColData& data) {
  // Don't create any entries with a variable width.
  if (data.HasVariableWidth()) {
    return nullptr;
  }

  ScopedIppPtr media_col = WrapIpp(ippNew());
  ScopedIppPtr media_size = WrapIpp(ippNew());

  ippAddInteger(media_size.get(), IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                kIppXDimension, data.min_width);
  if (data.HasVariableHeight()) {
    ippAddRange(media_size.get(), IPP_TAG_PRINTER, kIppYDimension,
                data.min_height, data.max_height);
  } else {
    ippAddInteger(media_size.get(), IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                  kIppYDimension, data.min_height);
  }
  ippAddCollection(media_col.get(), IPP_TAG_PRINTER, kIppMediaSize,
                   media_size.get());

  ippAddInteger(media_col.get(), IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                kIppMediaBottomMargin, data.bottom_margin);
  ippAddInteger(media_col.get(), IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                kIppMediaLeftMargin, data.left_margin);
  ippAddInteger(media_col.get(), IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                kIppMediaRightMargin, data.right_margin);
  ippAddInteger(media_col.get(), IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                kIppMediaTopMargin, data.top_margin);

  return media_col;
}

void FilterMediaColSizes(ScopedIppPtr& attributes) {
  if (!attributes) {
    return;
  }

  ipp_attribute_t* media_col_db = ippFindAttribute(
      attributes.get(), kIppMediaColDatabase, IPP_TAG_BEGIN_COLLECTION);
  if (!media_col_db) {
    return;
  }

  // `fixed_widths` is the width for any media-col-database entry that is
  // non-variable.  For instance, if the media-col-database has 4 fixed
  // widthxheight entries and one variable widthxheight entry like so:
  //
  // 58mmx200mm
  // 58mmx2000mm
  // 80mmx200mm
  // 80mmx2000mm
  // 10-80mmx20-2000mm
  //
  // then `fixed_widths` will contain 58 and 80.  After filtering, the following
  // sizes will exist:
  //
  // 58mmx200mm
  // 58mmx2000mm
  // 80mmx200mm
  // 80mmx2000mm
  // 58mmx20-2000mm
  // 80mmx20-2000mm
  std::set<int> fixed_widths;
  std::vector<ScopedIppPtr> new_entries;
  std::vector<MediaColData> variable_height_entries;

  // Loop over all the `media_col_db` entries and either add them to
  // `new_entries`, skip them, or save them in `variable_height_entries` so
  // they can be added later (once all the fixed widths have been discovered).
  for (int i = 0; i < ippGetCount(media_col_db); i++) {
    ipp_t* db_entry = ippGetCollection(media_col_db, i);
    absl::optional<MediaColData> size = ExtractMediaColData(db_entry);
    if (!size.has_value()) {
      return;
    }

    // TODO(nmuggli): Consider adding the boundaries of a variable-width entry
    // to `fixed_widths`.
    if (!size->HasVariableWidth()) {
      fixed_widths.insert(size->min_width);
    }

    // Handle four different cases:
    // 1.  Variable width and fixed height.  Skip this - variable widths are not
    // supported.
    // 2.  Fixed width and fixed height.  Add to the new array.
    // 3.  Fixed width and variable height.  Add to the new array.
    // 4.  Variable width and variable height.  Save this entry until after
    // all of the entries are processed.  For each fixed width that fits
    // within this variable width, a new entry will get added with the
    // variable height.

    // Case 1:  skip over this.
    if (size->HasVariableWidth() && !size->HasVariableHeight()) {
      continue;
    }

    // Case 2 and case 3 - add to `new_entries`.
    if (!size->HasVariableWidth()) {
      ScopedIppPtr new_entry = NewMediaCollection(size.value());
      if (new_entry) {
        new_entries.push_back(std::move(new_entry));
      }
      continue;
    }

    // Case 4: Save entry for later processing.
    variable_height_entries.push_back(size.value());
  }

  for (const MediaColData& variable_height_entry : variable_height_entries) {
    // For each fixed width, create a new media size entry for that width and a
    // variable height.
    for (int width : fixed_widths) {
      MediaColData size = variable_height_entry;
      // Ensure `width` fits within the variable width.
      if (width < size.min_width || width > size.max_width) {
        continue;
      }
      size.min_width = width;
      size.max_width = width;
      ScopedIppPtr new_entry = NewMediaCollection(size);
      if (new_entry) {
        new_entries.push_back(std::move(new_entry));
      }
    }
  }

  // Finally, update the attribute that was passed in with the new entries.
  ippDeleteAttribute(attributes.get(), media_col_db);
  std::vector<const ipp_t*> raw_entries(new_entries.size());
  base::ranges::transform(new_entries, raw_entries.begin(), &ScopedIppPtr::get);
  ippAddCollections(attributes.get(), IPP_TAG_PRINTER, kIppMediaColDatabase,
                    raw_entries.size(), raw_entries.data());
}

}  //  namespace printing
