// Copyright 2016 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_printer.h"

#include <cups/cups.h>

#include <string>
#include <utility>

#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/strings/string_number_conversions.h"
#include "printing/backend/cups_connection.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h"

namespace {

const char kCUPSPrinterInfoOpt[] = "printer-info";
const char kCUPSPrinterStateOpt[] = "printer-state";

}  // namespace

namespace printing {

CupsPrinter::CupsPrinter(http_t* http,
                         std::unique_ptr<cups_dest_t, DestinationDeleter> dest,
                         std::unique_ptr<cups_dinfo_t, DestInfoDeleter> info)
    : cups_http_(http),
      destination_(std::move(dest)),
      dest_info_(std::move(info)) {
  DCHECK(cups_http_);
  DCHECK(destination_);
}

CupsPrinter::CupsPrinter(CupsPrinter&& printer)
    : cups_http_(printer.cups_http_),
      destination_(std::move(printer.destination_)),
      dest_info_(std::move(printer.dest_info_)) {
  DCHECK(cups_http_);
  DCHECK(destination_);
}

CupsPrinter::~CupsPrinter() {}

bool CupsPrinter::is_default() const {
  return destination_->is_default;
}

ipp_attribute_t* CupsPrinter::GetSupportedOptionValues(
    const char* option_name) const {
  if (!InitializeDestInfo())
    return nullptr;

  return cupsFindDestSupported(cups_http_, destination_.get(), dest_info_.get(),
                               option_name);
}

std::vector<base::StringPiece> CupsPrinter::GetSupportedOptionValueStrings(
    const char* option_name) const {
  std::vector<base::StringPiece> values;
  ipp_attribute_t* attr = GetSupportedOptionValues(option_name);
  if (!attr)
    return values;

  base::StringPiece value;
  int num_options = ippGetCount(attr);
  for (int i = 0; i < num_options; ++i) {
    value.set(ippGetString(attr, i, nullptr));
    values.push_back(value);
  }

  return values;
}

ipp_attribute_t* CupsPrinter::GetDefaultOptionValue(
    const char* option_name) const {
  if (!InitializeDestInfo())
    return nullptr;

  return cupsFindDestDefault(cups_http_, destination_.get(), dest_info_.get(),
                             option_name);
}

bool CupsPrinter::CheckOptionSupported(const char* name,
                                       const char* value) const {
  if (!InitializeDestInfo())
    return false;

  int supported = cupsCheckDestSupported(cups_http_, destination_.get(),
                                         dest_info_.get(), name, value);
  return supported == 1;
}

bool CupsPrinter::ToPrinterInfo(PrinterBasicInfo* printer_info) const {
  const cups_dest_t* printer = destination_.get();

  printer_info->printer_name = printer->name;
  printer_info->is_default = printer->is_default;

  const char* info = cupsGetOption(kCUPSPrinterInfoOpt, printer->num_options,
                                   printer->options);
  if (info)
    printer_info->printer_description = info;

  const char* state = cupsGetOption(kCUPSPrinterStateOpt, printer->num_options,
                                    printer->options);
  if (state)
    base::StringToInt(state, &printer_info->printer_status);

  const char* drv_info = cupsGetOption(kDriverNameTagName,
                                       printer->num_options, printer->options);
  if (drv_info)
    printer_info->options[kDriverInfoTagName] = *drv_info;

  // Store printer options.
  for (int opt_index = 0; opt_index < printer->num_options; ++opt_index) {
    printer_info->options[printer->options[opt_index].name] =
        printer->options[opt_index].value;
  }

  return true;
}

std::string CupsPrinter::GetPPD() const {
  std::string ppd_contents;
  const char* printer_name = destination_->name;
  const char* ppd_path_str = cupsGetPPD2(cups_http_, printer_name);
  if (!ppd_path_str)
    return ppd_contents;

  // There is no reliable way right now to detect full and complete PPD
  // get downloaded. If we reach http timeout, it may simply return
  // downloaded part as a full response. It might be good enough to check
  // http->data_remaining or http->_data_remaining, unfortunately http_t
  // is an internal structure and fields are not exposed in CUPS headers.
  // httpGetLength or httpGetLength2 returning the full content size.
  // Comparing file size against that content length might be unreliable
  // since some http reponses are encoded and content_length > file size.
  // Let's just check for the obvious CUPS and http errors here.
  base::FilePath ppd_path(ppd_path_str);
  ipp_status_t error_code = cupsLastError();
  int http_error = httpError(cups_http_);
  if (error_code <= IPP_OK_EVENTS_COMPLETE && http_error == 0) {
    bool res = base::ReadFileToString(ppd_path, &ppd_contents);
    if (!res)
      ppd_contents.clear();
  } else {
    LOG(ERROR) << "Error downloading PPD file, name: " << destination_->name
               << ", CUPS error: " << static_cast<int>(error_code)
               << ", HTTP error: " << http_error;
  }

  base::DeleteFile(ppd_path, false);
  return ppd_contents;
}

std::string CupsPrinter::GetName() const {
  return std::string(destination_->name);
}

std::string CupsPrinter::GetMakeAndModel() const {
  const char* make_and_model =
      cupsGetOption(kDriverNameTagName, destination_->num_options,
                    destination_->options);

  return make_and_model ? std::string(make_and_model) : std::string();
}

bool CupsPrinter::IsAvailable() const {
  return InitializeDestInfo();
}

bool CupsPrinter::InitializeDestInfo() const {
  if (dest_info_)
    return true;

  dest_info_.reset(cupsCopyDestInfo(cups_http_, destination_.get()));
  return !!dest_info_;
}

ipp_status_t CupsPrinter::CreateJob(int* job_id,
                                    const std::string& title,
                                    const std::vector<cups_option_t>& options) {
  DCHECK(dest_info_) << "Verify availability before starting a print job";

  cups_option_t* data = const_cast<cups_option_t*>(
      options.data());  // createDestJob will not modify the data
  ipp_status_t create_status =
      cupsCreateDestJob(cups_http_, destination_.get(), dest_info_.get(),
                        job_id, title.c_str(), options.size(), data);

  return create_status;
}

bool CupsPrinter::StartDocument(int job_id,
                                const std::string& document_name,
                                bool last_document,
                                const std::vector<cups_option_t>& options) {
  DCHECK(dest_info_);
  DCHECK(job_id);

  cups_option_t* data = const_cast<cups_option_t*>(
      options.data());  // createStartDestDocument will not modify the data
  http_status_t start_doc_status =
      cupsStartDestDocument(cups_http_, destination_.get(), dest_info_.get(),
                            job_id, document_name.c_str(), CUPS_FORMAT_PDF,
                            options.size(), data, last_document ? 0 : 1);

  return start_doc_status == HTTP_CONTINUE;
}

bool CupsPrinter::StreamData(const std::vector<char>& buffer) {
  http_status_t status =
      cupsWriteRequestData(cups_http_, buffer.data(), buffer.size());
  return status == HTTP_STATUS_CONTINUE;
}

bool CupsPrinter::FinishDocument() {
  DCHECK(dest_info_);

  ipp_status_t status =
      cupsFinishDestDocument(cups_http_, destination_.get(), dest_info_.get());

  return status == IPP_STATUS_OK;
}

ipp_status_t CupsPrinter::CloseJob(int job_id) {
  DCHECK(dest_info_);
  DCHECK(job_id);

  return cupsCloseDestJob(cups_http_, destination_.get(), dest_info_.get(),
                          job_id);
}

bool CupsPrinter::CancelJob(int job_id) {
  DCHECK(job_id);

  // TODO(skau): Try to change back to cupsCancelDestJob().
  ipp_status_t status =
      cupsCancelJob2(cups_http_, destination_->name, job_id, 0 /*cancel*/);
  return status == IPP_STATUS_OK;
}

}  // namespace printing
