// Copyright (c) 2012 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/backend/cups_helper.h"

#include <cups/ppd.h>
#include <stddef.h>

#include <string>
#include <vector>

#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h"
#include "printing/units.h"
#include "url/gurl.h"

using base::EqualsCaseInsensitiveASCII;

namespace printing {

// This section contains helper code for PPD parsing for semantic capabilities.
namespace {

const char kColorDevice[] = "ColorDevice";
const char kColorModel[] = "ColorModel";
const char kColorMode[] = "ColorMode";
const char kProcessColorModel[] = "ProcessColorModel";
const char kPrintoutMode[] = "PrintoutMode";
const char kDraftGray[] = "Draft.Gray";
const char kHighGray[] = "High.Gray";

constexpr char kDuplex[] = "Duplex";
constexpr char kDuplexNone[] = "None";
constexpr char kDuplexTumble[] = "DuplexTumble";
constexpr char kPageSize[] = "PageSize";

// Brother printer specific options.
constexpr char kBrotherDuplex[] = "BRDuplex";
constexpr char kBrotherMonoColor[] = "BRMonoColor";
constexpr char kBrotherPrintQuality[] = "BRPrintQuality";

// Samsung printer specific options.
constexpr char kSamsungColorTrue[] = "True";
constexpr char kSamsungColorFalse[] = "False";

const double kMicronsPerPoint = 10.0f * kHundrethsMMPerInch / kPointsPerInch;

void ParseLpOptions(const base::FilePath& filepath,
                    base::StringPiece printer_name,
                    int* num_options,
                    cups_option_t** options) {
  std::string content;
  if (!base::ReadFileToString(filepath, &content))
    return;

  const char kDest[] = "dest";
  const char kDefault[] = "default";
  const size_t kDestLen = sizeof(kDest) - 1;
  const size_t kDefaultLen = sizeof(kDefault) - 1;

  for (base::StringPiece line :
       base::SplitStringPiece(content, "\n", base::KEEP_WHITESPACE,
                              base::SPLIT_WANT_NONEMPTY)) {
    if (base::StartsWith(line, base::StringPiece(kDefault, kDefaultLen),
                         base::CompareCase::INSENSITIVE_ASCII) &&
        isspace(line[kDefaultLen])) {
      line = line.substr(kDefaultLen);
    } else if (base::StartsWith(line, base::StringPiece(kDest, kDestLen),
                                base::CompareCase::INSENSITIVE_ASCII) &&
               isspace(line[kDestLen])) {
      line = line.substr(kDestLen);
    } else {
      continue;
    }

    line = base::TrimWhitespaceASCII(line, base::TRIM_ALL);
    if (line.empty())
      continue;

    size_t space_found = line.find(' ');
    if (space_found == base::StringPiece::npos)
      continue;

    base::StringPiece name = line.substr(0, space_found);
    if (name.empty())
      continue;

    if (!EqualsCaseInsensitiveASCII(printer_name, name))
      continue;  // This is not the required printer.

    line = line.substr(space_found + 1);
    // Remove extra spaces.
    line = base::TrimWhitespaceASCII(line, base::TRIM_ALL);
    if (line.empty())
      continue;

    // Parse the selected printer custom options. Need to pass a
    // null-terminated string.
    *num_options = cupsParseOptions(line.as_string().c_str(), 0, options);
  }
}

void MarkLpOptions(base::StringPiece printer_name, ppd_file_t** ppd) {
  cups_option_t* options = nullptr;
  int num_options = 0;

  const char kSystemLpOptionPath[] = "/etc/cups/lpoptions";
  const char kUserLpOptionPath[] = ".cups/lpoptions";

  std::vector<base::FilePath> file_locations;
  file_locations.push_back(base::FilePath(kSystemLpOptionPath));
  base::FilePath homedir;
  PathService::Get(base::DIR_HOME, &homedir);
  file_locations.push_back(base::FilePath(homedir.Append(kUserLpOptionPath)));

  for (const base::FilePath& location : file_locations) {
    num_options = 0;
    options = nullptr;
    ParseLpOptions(location, printer_name, &num_options, &options);
    if (num_options > 0 && options) {
      cupsMarkOptions(*ppd, num_options, options);
      cupsFreeOptions(num_options, options);
    }
  }
}

void GetDuplexSettings(ppd_file_t* ppd,
                       bool* duplex_capable,
                       DuplexMode* duplex_default) {
  ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex);
  if (!duplex_choice) {
    ppd_option_t* option = ppdFindOption(ppd, kDuplex);
    if (!option)
      option = ppdFindOption(ppd, kBrotherDuplex);
    if (!option)
      return;

    duplex_choice = ppdFindChoice(option, option->defchoice);
  }

  if (!duplex_choice)
    return;

  *duplex_capable = true;
  const char* choice = duplex_choice->choice;
  if (EqualsCaseInsensitiveASCII(choice, kDuplexNone)) {
    *duplex_default = SIMPLEX;
  } else if (EqualsCaseInsensitiveASCII(choice, kDuplexTumble)) {
    *duplex_default = SHORT_EDGE;
  } else {
    *duplex_default = LONG_EDGE;
  }
}

bool GetBasicColorModelSettings(ppd_file_t* ppd,
                                ColorModel* color_model_for_black,
                                ColorModel* color_model_for_color,
                                bool* color_is_default) {
  ppd_option_t* color_model = ppdFindOption(ppd, kColorModel);
  if (!color_model)
    return false;

  if (ppdFindChoice(color_model, kBlack))
    *color_model_for_black = BLACK;
  else if (ppdFindChoice(color_model, kGray))
    *color_model_for_black = GRAY;
  else if (ppdFindChoice(color_model, kGrayscale))
    *color_model_for_black = GRAYSCALE;

  if (ppdFindChoice(color_model, kColor))
    *color_model_for_color = COLOR;
  else if (ppdFindChoice(color_model, kCMYK))
    *color_model_for_color = CMYK;
  else if (ppdFindChoice(color_model, kRGB))
    *color_model_for_color = RGB;
  else if (ppdFindChoice(color_model, kRGBA))
    *color_model_for_color = RGBA;
  else if (ppdFindChoice(color_model, kRGB16))
    *color_model_for_color = RGB16;
  else if (ppdFindChoice(color_model, kCMY))
    *color_model_for_color = CMY;
  else if (ppdFindChoice(color_model, kKCMY))
    *color_model_for_color = KCMY;
  else if (ppdFindChoice(color_model, kCMY_K))
    *color_model_for_color = CMY_K;

  ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel);
  if (!marked_choice)
    marked_choice = ppdFindChoice(color_model, color_model->defchoice);

  if (marked_choice) {
    *color_is_default =
        !EqualsCaseInsensitiveASCII(marked_choice->choice, kBlack) &&
        !EqualsCaseInsensitiveASCII(marked_choice->choice, kGray) &&
        !EqualsCaseInsensitiveASCII(marked_choice->choice, kGrayscale);
  }
  return true;
}

bool GetPrintOutModeColorSettings(ppd_file_t* ppd,
                                  ColorModel* color_model_for_black,
                                  ColorModel* color_model_for_color,
                                  bool* color_is_default) {
  ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode);
  if (!printout_mode)
    return false;

  *color_model_for_color = PRINTOUTMODE_NORMAL;
  *color_model_for_black = PRINTOUTMODE_NORMAL;

  // Check to see if NORMAL_GRAY value is supported by PrintoutMode.
  // If NORMAL_GRAY is not supported, NORMAL value is used to
  // represent grayscale. If NORMAL_GRAY is supported, NORMAL is used to
  // represent color.
  if (ppdFindChoice(printout_mode, kNormalGray))
    *color_model_for_black = PRINTOUTMODE_NORMAL_GRAY;

  // Get the default marked choice to identify the default color setting
  // value.
  ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode);
  if (!printout_mode_choice) {
      printout_mode_choice = ppdFindChoice(printout_mode,
                                           printout_mode->defchoice);
  }
  if (printout_mode_choice) {
    if (EqualsCaseInsensitiveASCII(printout_mode_choice->choice, kNormalGray) ||
        EqualsCaseInsensitiveASCII(printout_mode_choice->choice, kHighGray) ||
        EqualsCaseInsensitiveASCII(printout_mode_choice->choice, kDraftGray)) {
      *color_model_for_black = PRINTOUTMODE_NORMAL_GRAY;
      *color_is_default = false;
    }
  }
  return true;
}

bool GetColorModeSettings(ppd_file_t* ppd,
                          ColorModel* color_model_for_black,
                          ColorModel* color_model_for_color,
                          bool* color_is_default) {
  // Samsung printers use "ColorMode" attribute in their PPDs.
  ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode);
  if (!color_mode_option)
    return false;

  if (ppdFindChoice(color_mode_option, kColor) ||
      ppdFindChoice(color_mode_option, kSamsungColorTrue)) {
    *color_model_for_color = COLORMODE_COLOR;
  }

  if (ppdFindChoice(color_mode_option, kMonochrome) ||
      ppdFindChoice(color_mode_option, kSamsungColorFalse)) {
    *color_model_for_black = COLORMODE_MONOCHROME;
  }

  ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode);
  if (!mode_choice) {
    mode_choice = ppdFindChoice(color_mode_option,
                                color_mode_option->defchoice);
  }

  if (mode_choice) {
    *color_is_default =
        EqualsCaseInsensitiveASCII(mode_choice->choice, kColor) ||
        EqualsCaseInsensitiveASCII(mode_choice->choice, kSamsungColorTrue);
  }
  return true;
}

bool GetBrotherColorSettings(ppd_file_t* ppd,
                             ColorModel* color_model_for_black,
                             ColorModel* color_model_for_color,
                             bool* color_is_default) {
  // Some Brother printers use "BRMonoColor" attribute in their PPDs.
  // Some Brother printers use "BRPrintQuality" attribute in their PPDs.
  ppd_option_t* color_mode_option = ppdFindOption(ppd, kBrotherMonoColor);
  if (!color_mode_option)
    color_mode_option = ppdFindOption(ppd, kBrotherPrintQuality);
  if (!color_mode_option)
    return false;

  if (ppdFindChoice(color_mode_option, kFullColor))
    *color_model_for_color = BROTHER_CUPS_COLOR;
  else if (ppdFindChoice(color_mode_option, kColor))
    *color_model_for_color = BROTHER_BRSCRIPT3_COLOR;

  if (ppdFindChoice(color_mode_option, kMono))
    *color_model_for_black = BROTHER_CUPS_MONO;
  else if (ppdFindChoice(color_mode_option, kBlack))
    *color_model_for_black = BROTHER_BRSCRIPT3_BLACK;

  ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorMode);
  if (!marked_choice) {
    marked_choice =
        ppdFindChoice(color_mode_option, color_mode_option->defchoice);
  }
  if (marked_choice) {
    *color_is_default =
        !EqualsCaseInsensitiveASCII(marked_choice->choice, kBlack) &&
        !EqualsCaseInsensitiveASCII(marked_choice->choice, kMono);
  }
  return true;
}

bool GetHPColorSettings(ppd_file_t* ppd,
                        ColorModel* color_model_for_black,
                        ColorModel* color_model_for_color,
                        bool* color_is_default) {
  // HP printers use "Color/Color Model" attribute in their PPDs.
  ppd_option_t* color_mode_option = ppdFindOption(ppd, kColor);
  if (!color_mode_option)
    return false;

  if (ppdFindChoice(color_mode_option, kColor))
    *color_model_for_color = HP_COLOR_COLOR;
  if (ppdFindChoice(color_mode_option, kBlack))
    *color_model_for_black = HP_COLOR_BLACK;

  ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode);
  if (!mode_choice) {
    mode_choice = ppdFindChoice(color_mode_option,
                                color_mode_option->defchoice);
  }
  if (mode_choice) {
    *color_is_default = EqualsCaseInsensitiveASCII(mode_choice->choice, kColor);
  }
  return true;
}

bool GetProcessColorModelSettings(ppd_file_t* ppd,
                                  ColorModel* color_model_for_black,
                                  ColorModel* color_model_for_color,
                                  bool* color_is_default) {
  // Canon printers use "ProcessColorModel" attribute in their PPDs.
  ppd_option_t* color_mode_option =  ppdFindOption(ppd, kProcessColorModel);
  if (!color_mode_option)
    return false;

  if (ppdFindChoice(color_mode_option, kRGB))
    *color_model_for_color = PROCESSCOLORMODEL_RGB;
  else if (ppdFindChoice(color_mode_option, kCMYK))
    *color_model_for_color = PROCESSCOLORMODEL_CMYK;

  if (ppdFindChoice(color_mode_option, kGreyscale))
    *color_model_for_black = PROCESSCOLORMODEL_GREYSCALE;

  ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel);
  if (!mode_choice) {
    mode_choice = ppdFindChoice(color_mode_option,
                                color_mode_option->defchoice);
  }

  if (mode_choice) {
    *color_is_default =
        !EqualsCaseInsensitiveASCII(mode_choice->choice, kGreyscale);
  }
  return true;
}

bool GetColorModelSettings(ppd_file_t* ppd,
                           ColorModel* cm_black,
                           ColorModel* cm_color,
                           bool* is_color) {
  bool is_color_device = false;
  ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, nullptr);
  if (attr && attr->value)
    is_color_device = ppd->color_device;

  *is_color = is_color_device;
  return (is_color_device &&
          GetBasicColorModelSettings(ppd, cm_black, cm_color, is_color)) ||
         GetPrintOutModeColorSettings(ppd, cm_black, cm_color, is_color) ||
         GetColorModeSettings(ppd, cm_black, cm_color, is_color) ||
         GetHPColorSettings(ppd, cm_black, cm_color, is_color) ||
         GetBrotherColorSettings(ppd, cm_black, cm_color, is_color) ||
         GetProcessColorModelSettings(ppd, cm_black, cm_color, is_color);
}

// Default port for IPP print servers.
const int kDefaultIPPServerPort = 631;

}  // namespace

// Helper wrapper around http_t structure, with connection and cleanup
// functionality.
HttpConnectionCUPS::HttpConnectionCUPS(const GURL& print_server_url,
                                       http_encryption_t encryption)
    : http_(nullptr) {
  // If we have an empty url, use default print server.
  if (print_server_url.is_empty())
    return;

  int port = print_server_url.IntPort();
  if (port == url::PORT_UNSPECIFIED)
    port = kDefaultIPPServerPort;

  http_ = httpConnectEncrypt(print_server_url.host().c_str(), port, encryption);
  if (!http_) {
    LOG(ERROR) << "CP_CUPS: Failed connecting to print server: "
               << print_server_url;
  }
}

HttpConnectionCUPS::~HttpConnectionCUPS() {
  if (http_)
    httpClose(http_);
}

void HttpConnectionCUPS::SetBlocking(bool blocking) {
  httpBlocking(http_, blocking ?  1 : 0);
}

http_t* HttpConnectionCUPS::http() {
  return http_;
}

bool ParsePpdCapabilities(base::StringPiece printer_name,
                          base::StringPiece printer_capabilities,
                          PrinterSemanticCapsAndDefaults* printer_info) {
  base::FilePath ppd_file_path;
  if (!base::CreateTemporaryFile(&ppd_file_path))
    return false;

  int data_size = printer_capabilities.length();
  if (data_size != base::WriteFile(
                       ppd_file_path,
                       printer_capabilities.data(),
                       data_size)) {
    base::DeleteFile(ppd_file_path, false);
    return false;
  }

  ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str());
  if (!ppd) {
    int line = 0;
    ppd_status_t ppd_status = ppdLastError(&line);
    LOG(ERROR) << "Failed to open PDD file: error " << ppd_status << " at line "
               << line << ", " << ppdErrorString(ppd_status);
    return false;
  }
  ppdMarkDefaults(ppd);
  MarkLpOptions(printer_name, &ppd);

  PrinterSemanticCapsAndDefaults caps;
  caps.collate_capable = true;
  caps.collate_default = true;
  caps.copies_capable = true;

  GetDuplexSettings(ppd, &caps.duplex_capable, &caps.duplex_default);

  bool is_color = false;
  ColorModel cm_color = UNKNOWN_COLOR_MODEL, cm_black = UNKNOWN_COLOR_MODEL;
  if (!GetColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) {
    VLOG(1) << "Unknown printer color model";
  }

  caps.color_changeable = ((cm_color != UNKNOWN_COLOR_MODEL) &&
                           (cm_black != UNKNOWN_COLOR_MODEL) &&
                           (cm_color != cm_black));
  caps.color_default = is_color;
  caps.color_model = cm_color;
  caps.bw_model = cm_black;

  if (ppd->num_sizes > 0 && ppd->sizes) {
    VLOG(1) << "Paper list size - " << ppd->num_sizes;
    ppd_option_t* paper_option = ppdFindOption(ppd, kPageSize);
    for (int i = 0; i < ppd->num_sizes; ++i) {
      gfx::Size paper_size_microns(
          static_cast<int>(ppd->sizes[i].width * kMicronsPerPoint + 0.5),
          static_cast<int>(ppd->sizes[i].length * kMicronsPerPoint + 0.5));
      if (paper_size_microns.width() > 0 && paper_size_microns.height() > 0) {
        PrinterSemanticCapsAndDefaults::Paper paper;
        paper.size_um = paper_size_microns;
        paper.vendor_id = ppd->sizes[i].name;
        if (paper_option) {
          ppd_choice_t* paper_choice =
              ppdFindChoice(paper_option, ppd->sizes[i].name);
          // Human readable paper name should be UTF-8 encoded, but some PPDs
          // do not follow this standard.
          if (paper_choice && base::IsStringUTF8(paper_choice->text)) {
            paper.display_name = paper_choice->text;
          }
        }
        caps.papers.push_back(paper);
        if (i == 0 || ppd->sizes[i].marked) {
          caps.default_paper = paper;
        }
      }
    }
  }

  ppdClose(ppd);
  base::DeleteFile(ppd_file_path, false);

  *printer_info = caps;
  return true;
}

}  // namespace printing
