// 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 "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h"

#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/containers/flat_map.h"
#include "base/files/file_util.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/printing/cups_printers_manager.h"
#include "chrome/browser/chromeos/printing/ppd_provider_factory.h"
#include "chrome/browser/chromeos/printing/printer_configurer.h"
#include "chrome/browser/chromeos/printing/printer_event_tracker.h"
#include "chrome/browser/chromeos/printing/printer_event_tracker_factory.h"
#include "chrome/browser/chromeos/printing/printer_info.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/common/chrome_paths.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/debug_daemon_client.h"
#include "chromeos/printing/ppd_cache.h"
#include "chromeos/printing/ppd_line_reader.h"
#include "chromeos/printing/ppd_provider.h"
#include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/printing_constants.h"
#include "chromeos/printing/uri_components.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_ui.h"
#include "google_apis/google_api_keys.h"
#include "net/base/filename_util.h"
#include "net/url_request/url_request_context_getter.h"
#include "printing/backend/print_backend.h"

namespace chromeos {
namespace settings {

namespace {

// These values are written to logs.  New enum values can be added, but existing
// enums must never be renumbered or deleted and reused.
enum PpdSourceForHistogram { kUser = 0, kScs = 1, kPpdSourceMax };

constexpr int kPpdMaxLineLength = 255;

void RecordPpdSource(const PpdSourceForHistogram& source) {
  UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PpdSource", source, kPpdSourceMax);
}

void OnRemovedPrinter(const Printer::PrinterProtocol& protocol, bool success) {
  UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterRemoved", protocol,
                            Printer::PrinterProtocol::kProtocolMax);
}

// Log if the IPP attributes request was succesful.
void RecordIppQuerySuccess(bool success) {
  UMA_HISTOGRAM_BOOLEAN("Printing.CUPS.IppAttributesSuccess", success);
}

// Returns true if |printer_uri| is an IPP uri.
bool IsIppUri(base::StringPiece printer_uri) {
  base::StringPiece::size_type separator_location =
      printer_uri.find(url::kStandardSchemeSeparator);
  if (separator_location == base::StringPiece::npos) {
    return false;
  }

  base::StringPiece scheme_part = printer_uri.substr(0, separator_location);
  return scheme_part == kIppScheme || scheme_part == kIppsScheme;
}

// Query an IPP printer to check for autoconf support where the printer is
// located at |printer_uri|.  Results are reported through |callback|.  It is an
// error to attempt this with a non-IPP printer.
void QueryAutoconf(const std::string& printer_uri,
                   const PrinterInfoCallback& callback) {
  auto optional = ParseUri(printer_uri);
  // Behavior for querying a non-IPP uri is undefined and disallowed.
  if (!IsIppUri(printer_uri) || !optional.has_value()) {
    LOG(WARNING) << "Printer uri is invalid: " << printer_uri;
    callback.Run(false, "", "", "", false);
    return;
  }

  UriComponents uri = optional.value();
  QueryIppPrinter(uri.host(), uri.port(), uri.path(), uri.encrypted(),
                  callback);
}

// Create an empty CupsPrinterInfo dictionary value. It should be consistent
// with the fields in js side. See cups_printers_browser_proxy.js for the
// definition of CupsPrinterInfo.
std::unique_ptr<base::DictionaryValue> CreateEmptyPrinterInfo() {
  std::unique_ptr<base::DictionaryValue> printer_info =
      std::make_unique<base::DictionaryValue>();
  printer_info->SetString("ppdManufacturer", "");
  printer_info->SetString("ppdModel", "");
  printer_info->SetString("printerAddress", "");
  printer_info->SetBoolean("printerAutoconf", false);
  printer_info->SetString("printerDescription", "");
  printer_info->SetString("printerId", "");
  printer_info->SetString("printerManufacturer", "");
  printer_info->SetString("printerModel", "");
  printer_info->SetString("printerMakeAndModel", "");
  printer_info->SetString("printerName", "");
  printer_info->SetString("printerPPDPath", "");
  printer_info->SetString("printerProtocol", "ipp");
  printer_info->SetString("printerQueue", "");
  printer_info->SetString("printerStatus", "");
  return printer_info;
}

// Formats a host and port string.  The |port| portion is omitted if
// it is unspecified or invalid.
std::string PrinterAddress(const std::string& host, int port) {
  if (port != url::PORT_UNSPECIFIED && port != url::PORT_INVALID) {
    return base::StringPrintf("%s:%d", host.c_str(), port);
  }

  return host;
}

// Returns a JSON representation of |printer| as a CupsPrinterInfo. If the
// printer uri cannot be parsed, the relevant fields are populated with default
// values.
std::unique_ptr<base::DictionaryValue> GetPrinterInfo(const Printer& printer) {
  std::unique_ptr<base::DictionaryValue> printer_info =
      CreateEmptyPrinterInfo();
  printer_info->SetString("printerId", printer.id());
  printer_info->SetString("printerName", printer.display_name());
  printer_info->SetString("printerDescription", printer.description());
  printer_info->SetString("printerManufacturer", printer.manufacturer());
  printer_info->SetString("printerModel", printer.model());
  printer_info->SetString("printerMakeAndModel", printer.make_and_model());

  auto optional = printer.GetUriComponents();
  if (!optional.has_value()) {
    // Uri is invalid so we set default values.
    LOG(WARNING) << "Could not parse uri.  Defaulting values";
    printer_info->SetString("printerAddress", "");
    printer_info->SetString("printerQueue", "");
    printer_info->SetString("printerProtocol",
                            "ipp");  // IPP is our default protocol.
    return printer_info;
  }

  UriComponents uri = optional.value();

  if (base::ToLowerASCII(uri.scheme()) == "usb") {
    // USB has URI path (and, maybe, query) components that aren't really
    // associated with a queue -- the mapping between printing semantics and URI
    // semantics breaks down a bit here.  From the user's point of view, the
    // entire host/path/query block is the printer address for USB.
    printer_info->SetString("printerAddress",
                            printer.uri().substr(strlen("usb://")));
  } else {
    printer_info->SetString("printerAddress",
                            PrinterAddress(uri.host(), uri.port()));
    if (!uri.path().empty()) {
      printer_info->SetString("printerQueue", uri.path().substr(1));
    }
  }
  printer_info->SetString("printerProtocol", base::ToLowerASCII(uri.scheme()));

  return printer_info;
}

// Extracts a sanitized value of printerQueue from |printer_dict|.  Returns an
// empty string if the value was not present in the dictionary.
std::string GetPrinterQueue(const base::DictionaryValue& printer_dict) {
  std::string queue;
  if (!printer_dict.GetString("printerQueue", &queue)) {
    return queue;
  }

  if (!queue.empty() && queue[0] == '/') {
    // Strip the leading backslash. It is expected that this results in an
    // empty string if the input is just a backslash.
    queue = queue.substr(1);
  }

  return queue;
}

// Generates a Printer from |printer_dict| where |printer_dict| is a
// CupsPrinterInfo representation.  If any of the required fields are missing,
// returns nullptr.
std::unique_ptr<chromeos::Printer> DictToPrinter(
    const base::DictionaryValue& printer_dict) {
  std::string printer_id;
  std::string printer_name;
  std::string printer_description;
  std::string printer_manufacturer;
  std::string printer_model;
  std::string printer_make_and_model;
  std::string printer_address;
  std::string printer_protocol;

  if (!printer_dict.GetString("printerId", &printer_id) ||
      !printer_dict.GetString("printerName", &printer_name) ||
      !printer_dict.GetString("printerDescription", &printer_description) ||
      !printer_dict.GetString("printerManufacturer", &printer_manufacturer) ||
      !printer_dict.GetString("printerModel", &printer_model) ||
      !printer_dict.GetString("printerMakeAndModel", &printer_make_and_model) ||
      !printer_dict.GetString("printerAddress", &printer_address) ||
      !printer_dict.GetString("printerProtocol", &printer_protocol)) {
    return nullptr;
  }

  std::string printer_queue = GetPrinterQueue(printer_dict);

  std::string printer_uri =
      printer_protocol + url::kStandardSchemeSeparator + printer_address;
  if (!printer_queue.empty()) {
    printer_uri += "/" + printer_queue;
  }

  auto printer = std::make_unique<chromeos::Printer>(printer_id);
  printer->set_display_name(printer_name);
  printer->set_description(printer_description);
  printer->set_manufacturer(printer_manufacturer);
  printer->set_model(printer_model);
  printer->set_make_and_model(printer_make_and_model);
  printer->set_uri(printer_uri);

  return printer;
}

std::string ReadFileToStringWithMaxSize(const base::FilePath& path,
                                        int max_size) {
  std::string contents;
  // This call can fail, but it doesn't matter for our purposes. If it fails,
  // we simply return an empty string for the contents, and it will be rejected
  // as an invalid PPD.
  base::ReadFileToStringWithMaxSize(path, &contents, max_size);
  return contents;
}

}  // namespace

CupsPrintersHandler::CupsPrintersHandler(content::WebUI* webui)
    : profile_(Profile::FromWebUI(webui)),
      ppd_provider_(CreatePpdProvider(profile_)),
      printer_configurer_(PrinterConfigurer::Create(profile_)),
      printers_manager_(CupsPrintersManager::Create(profile_)),
      weak_factory_(this) {}

CupsPrintersHandler::~CupsPrintersHandler() {}

void CupsPrintersHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      "getCupsPrintersList",
      base::BindRepeating(&CupsPrintersHandler::HandleGetCupsPrintersList,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "updateCupsPrinter",
      base::BindRepeating(&CupsPrintersHandler::HandleUpdateCupsPrinter,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "removeCupsPrinter",
      base::BindRepeating(&CupsPrintersHandler::HandleRemoveCupsPrinter,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "addCupsPrinter",
      base::BindRepeating(&CupsPrintersHandler::HandleAddCupsPrinter,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getPrinterInfo",
      base::BindRepeating(&CupsPrintersHandler::HandleGetPrinterInfo,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getCupsPrinterManufacturersList",
      base::BindRepeating(
          &CupsPrintersHandler::HandleGetCupsPrinterManufacturers,
          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getCupsPrinterModelsList",
      base::BindRepeating(&CupsPrintersHandler::HandleGetCupsPrinterModels,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "selectPPDFile",
      base::BindRepeating(&CupsPrintersHandler::HandleSelectPPDFile,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "startDiscoveringPrinters",
      base::BindRepeating(&CupsPrintersHandler::HandleStartDiscovery,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "stopDiscoveringPrinters",
      base::BindRepeating(&CupsPrintersHandler::HandleStopDiscovery,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "getPrinterPpdManufacturerAndModel",
      base::BindRepeating(
          &CupsPrintersHandler::HandleGetPrinterPpdManufacturerAndModel,
          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "addDiscoveredPrinter",
      base::BindRepeating(&CupsPrintersHandler::HandleAddDiscoveredPrinter,
                          base::Unretained(this)));
  web_ui()->RegisterMessageCallback(
      "cancelPrinterSetUp",
      base::BindRepeating(&CupsPrintersHandler::HandleSetUpCancel,
                          base::Unretained(this)));
}

void CupsPrintersHandler::OnJavascriptAllowed() {
  printers_manager_->AddObserver(this);
}

void CupsPrintersHandler::OnJavascriptDisallowed() {
  printers_manager_->RemoveObserver(this);
}

void CupsPrintersHandler::HandleGetCupsPrintersList(
    const base::ListValue* args) {
  AllowJavascript();

  CHECK_EQ(1U, args->GetSize());
  std::string callback_id;
  CHECK(args->GetString(0, &callback_id));

  std::vector<Printer> printers =
      printers_manager_->GetPrinters(CupsPrintersManager::kConfigured);

  auto printers_list = std::make_unique<base::ListValue>();
  for (const Printer& printer : printers) {
    // Some of these printers could be invalid but we want to allow the user
    // to edit them. crbug.com/778383
    printers_list->Append(GetPrinterInfo(printer));
  }

  auto response = std::make_unique<base::DictionaryValue>();
  response->Set("printerList", std::move(printers_list));
  ResolveJavascriptCallback(base::Value(callback_id), *response);
}

void CupsPrintersHandler::HandleUpdateCupsPrinter(const base::ListValue* args) {
  std::string printer_id;
  std::string printer_name;
  CHECK(args->GetString(0, &printer_id));
  CHECK(args->GetString(1, &printer_name));

  Printer printer(printer_id);
  printer.set_display_name(printer_name);
  printers_manager_->UpdateConfiguredPrinter(printer);

  // TODO(xdai): Replace "on-add-cups-printer" callback with Promise resolve
  // function.
  FireWebUIListener("on-add-cups-printer", base::Value(true),
                    base::Value(printer_name));
}

void CupsPrintersHandler::HandleRemoveCupsPrinter(const base::ListValue* args) {
  std::string printer_id;
  std::string printer_name;
  CHECK(args->GetString(0, &printer_id));
  CHECK(args->GetString(1, &printer_name));
  auto printer = printers_manager_->GetPrinter(printer_id);
  if (!printer)
    return;

  // Record removal before the printer is deleted.
  PrinterEventTrackerFactory::GetForBrowserContext(profile_)
      ->RecordPrinterRemoved(*printer);

  Printer::PrinterProtocol protocol = printer->GetProtocol();
  // Printer is deleted here.  Do not access after this line.
  printers_manager_->RemoveConfiguredPrinter(printer_id);

  DebugDaemonClient* client = DBusThreadManager::Get()->GetDebugDaemonClient();
  client->CupsRemovePrinter(
      printer_name, base::Bind(&OnRemovedPrinter, protocol), base::DoNothing());
}

void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) {
  DCHECK(args);
  std::string callback_id;
  if (!args->GetString(0, &callback_id)) {
    NOTREACHED() << "Expected request for a promise";
    return;
  }

  const base::DictionaryValue* printer_dict = nullptr;
  if (!args->GetDictionary(1, &printer_dict)) {
    NOTREACHED() << "Dictionary missing";
    return;
  }

  AllowJavascript();

  std::string printer_address;
  if (!printer_dict->GetString("printerAddress", &printer_address)) {
    NOTREACHED() << "Address missing";
    return;
  }

  if (printer_address.empty()) {
    // Run the failure callback.
    OnAutoconfQueried(callback_id, false, "", "", "", false);
    return;
  }

  std::string printer_queue = GetPrinterQueue(*printer_dict);

  std::string printer_protocol;
  if (!printer_dict->GetString("printerProtocol", &printer_protocol)) {
    NOTREACHED() << "Protocol missing";
    return;
  }

  DCHECK(printer_protocol == kIppScheme || printer_protocol == kIppsScheme)
      << "Printer info requests only supported for IPP and IPPS printers";
  std::string printer_uri =
      base::StringPrintf("%s://%s/%s", printer_protocol.c_str(),
                         printer_address.c_str(), printer_queue.c_str());
  QueryAutoconf(printer_uri,
                base::Bind(&CupsPrintersHandler::OnAutoconfQueried,
                           weak_factory_.GetWeakPtr(), callback_id));
}

void CupsPrintersHandler::OnAutoconfQueriedDiscovered(
    std::unique_ptr<Printer> printer,
    bool success,
    const std::string& make,
    const std::string& model,
    const std::string& make_and_model,
    bool ipp_everywhere) {
  RecordIppQuerySuccess(success);

  if (success) {
    // If we queried a valid make and model, use it.  The mDNS record isn't
    // guaranteed to have it.  However, don't overwrite it if the printer
    // advertises an empty value through printer-make-and-model.
    if (!make_and_model.empty()) {
      // manufacturer and model are set with make_and_model because they are
      // derived from make_and_model for compatability and are slated for
      // removal.
      printer->set_manufacturer(make);
      printer->set_model(model);
      printer->set_make_and_model(make_and_model);
    }

    // Autoconfig available, use it.
    if (ipp_everywhere) {
      printer->mutable_ppd_reference()->autoconf = true;
      printer_configurer_->SetUpPrinter(
          *printer, base::Bind(&CupsPrintersHandler::OnAddedDiscoveredPrinter,
                               weak_factory_.GetWeakPtr(), *printer));
      return;
    }
  }

  // We don't have enough from discovery to configure the printer.  Fill in as
  // much information as we can about the printer, and ask the user to supply
  // the rest.
  FireWebUIListener("on-manually-add-discovered-printer",
                    *GetPrinterInfo(*printer));
}

void CupsPrintersHandler::OnAutoconfQueried(const std::string& callback_id,
                                            bool success,
                                            const std::string& make,
                                            const std::string& model,
                                            const std::string& make_and_model,
                                            bool ipp_everywhere) {
  RecordIppQuerySuccess(success);

  if (!success) {
    base::DictionaryValue reject;
    reject.SetString("message", "Querying printer failed");
    RejectJavascriptCallback(base::Value(callback_id), reject);
    return;
  }

  base::DictionaryValue info;
  info.SetString("manufacturer", make);
  info.SetString("model", model);
  info.SetString("makeAndModel", make_and_model);
  info.SetBoolean("autoconf", ipp_everywhere);
  ResolveJavascriptCallback(base::Value(callback_id), info);
}

void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
  AllowJavascript();

  const base::DictionaryValue* printer_dict = nullptr;
  CHECK(args->GetDictionary(0, &printer_dict));

  std::unique_ptr<Printer> printer = DictToPrinter(*printer_dict);
  if (!printer) {
    LOG(ERROR) << "Failed to parse printer URI";
    OnAddPrinterError(PrinterSetupResult::kFatalError);
    return;
  }

  auto optional = printer->GetUriComponents();
  if (!optional.has_value()) {
    // If the returned optional does not contain a value then it means that the
    // printer's uri was not able to be parsed successfully.
    LOG(ERROR) << "Failed to parse printer URI";
    OnAddPrinterError(PrinterSetupResult::kFatalError);
    return;
  }

  // Read PPD selection if it was used.
  std::string ppd_manufacturer;
  std::string ppd_model;
  printer_dict->GetString("ppdManufacturer", &ppd_manufacturer);
  printer_dict->GetString("ppdModel", &ppd_model);

  // Read user provided PPD if it was used.
  std::string printer_ppd_path;
  printer_dict->GetString("printerPPDPath", &printer_ppd_path);

  bool autoconf = false;
  printer_dict->GetBoolean("printerAutoconf", &autoconf);

  // Verify that the printer is autoconf or a valid ppd path is present.
  if (autoconf) {
    printer->mutable_ppd_reference()->autoconf = true;
  } else if (!printer_ppd_path.empty()) {
    RecordPpdSource(kUser);
    GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path));
    if (!tmp.is_valid()) {
      LOG(ERROR) << "Invalid ppd path: " << printer_ppd_path;
      OnAddPrinterError(PrinterSetupResult::kInvalidPpd);
      return;
    }
    printer->mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec();
  } else if (!ppd_manufacturer.empty() && !ppd_model.empty()) {
    RecordPpdSource(kScs);
    // Pull out the ppd reference associated with the selected manufacturer and
    // model.
    bool found = false;
    for (const auto& resolved_printer : resolved_printers_[ppd_manufacturer]) {
      if (resolved_printer.name == ppd_model) {
        *(printer->mutable_ppd_reference()) = resolved_printer.ppd_ref;
        found = true;
        break;
      }
    }
    if (!found) {
      LOG(ERROR) << "Failed to get ppd reference";
      OnAddPrinterError(PrinterSetupResult::kPpdNotFound);
      return;
    }

    if (printer->make_and_model().empty()) {
      // In lieu of more accurate information, populate the make and model
      // fields with the PPD information.
      printer->set_manufacturer(ppd_manufacturer);
      printer->set_model(ppd_model);
      // PPD Model names are actually make and model.
      printer->set_make_and_model(ppd_model);
    }
  } else {
    // TODO(crbug.com/738514): Support PPD guessing for non-autoconf printers.
    // i.e. !autoconf && !manufacturer.empty() && !model.empty()
    NOTREACHED()
        << "A configuration option must have been selected to add a printer";
  }

  printer_configurer_->SetUpPrinter(
      *printer, base::Bind(&CupsPrintersHandler::OnAddedSpecifiedPrinter,
                           weak_factory_.GetWeakPtr(), *printer));
}

void CupsPrintersHandler::OnAddedPrinterCommon(const Printer& printer,
                                               PrinterSetupResult result_code) {
  UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterSetupResult", result_code,
                            PrinterSetupResult::kMaxValue);
  switch (result_code) {
    case PrinterSetupResult::kSuccess:
      UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded",
                                printer.GetProtocol(), Printer::kProtocolMax);
      printers_manager_->PrinterInstalled(printer);
      printers_manager_->UpdateConfiguredPrinter(printer);
      return;
    case PrinterSetupResult::kPpdNotFound:
      LOG(WARNING) << "Could not locate requested PPD";
      break;
    case PrinterSetupResult::kPpdTooLarge:
      LOG(WARNING) << "PPD is too large";
      break;
    case PrinterSetupResult::kPpdUnretrievable:
      LOG(WARNING) << "Could not retrieve PPD from server";
      break;
    case PrinterSetupResult::kInvalidPpd:
      LOG(WARNING) << "Provided PPD is invalid.";
      break;
    case PrinterSetupResult::kPrinterUnreachable:
      LOG(WARNING) << "Could not contact printer for configuration";
      break;
    case PrinterSetupResult::kDbusError:
    case PrinterSetupResult::kFatalError:
      LOG(ERROR) << "Unrecoverable error.  Reboot required.";
      break;
    case PrinterSetupResult::kMaxValue:
      NOTREACHED() << "This is not an expected value";
      break;
  }
  // Log an event that tells us this printer setup failed, so we can get
  // statistics about which printers are giving users difficulty.
  printers_manager_->RecordSetupAbandoned(printer);
}

void CupsPrintersHandler::OnAddedDiscoveredPrinter(
    const Printer& printer,
    PrinterSetupResult result_code) {
  OnAddedPrinterCommon(printer, result_code);
  if (result_code == PrinterSetupResult::kSuccess) {
    FireWebUIListener("on-add-cups-printer", base::Value(result_code),
                      base::Value(printer.display_name()));
  } else {
    FireWebUIListener("on-manually-add-discovered-printer",
                      base::Value(result_code == PrinterSetupResult::kSuccess),
                      base::Value(printer.display_name()));
  }
}

void CupsPrintersHandler::OnAddedSpecifiedPrinter(
    const Printer& printer,
    PrinterSetupResult result_code) {
  OnAddedPrinterCommon(printer, result_code);
  FireWebUIListener("on-add-cups-printer", base::Value(result_code),
                    base::Value(printer.display_name()));
}

void CupsPrintersHandler::OnAddPrinterError(PrinterSetupResult result_code) {
  FireWebUIListener("on-add-cups-printer", base::Value(result_code),
                    base::Value(""));
}

void CupsPrintersHandler::HandleGetCupsPrinterManufacturers(
    const base::ListValue* args) {
  AllowJavascript();
  std::string js_callback;
  CHECK_EQ(1U, args->GetSize());
  CHECK(args->GetString(0, &js_callback));
  ppd_provider_->ResolveManufacturers(
      base::Bind(&CupsPrintersHandler::ResolveManufacturersDone,
                 weak_factory_.GetWeakPtr(), js_callback));
}

void CupsPrintersHandler::HandleGetCupsPrinterModels(
    const base::ListValue* args) {
  AllowJavascript();
  std::string js_callback;
  std::string manufacturer;
  CHECK_EQ(2U, args->GetSize());
  CHECK(args->GetString(0, &js_callback));
  CHECK(args->GetString(1, &manufacturer));

  // Empty manufacturer queries may be triggered as a part of the ui
  // initialization, and should just return empty results.
  if (manufacturer.empty()) {
    base::DictionaryValue response;
    response.SetBoolean("success", true);
    response.Set("models", std::make_unique<base::ListValue>());
    ResolveJavascriptCallback(base::Value(js_callback), response);
    return;
  }

  ppd_provider_->ResolvePrinters(
      manufacturer,
      base::Bind(&CupsPrintersHandler::ResolvePrintersDone,
                 weak_factory_.GetWeakPtr(), manufacturer, js_callback));
}

void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) {
  CHECK_EQ(1U, args->GetSize());
  CHECK(args->GetString(0, &webui_callback_id_));

  base::FilePath downloads_path =
      DownloadPrefs::FromDownloadManager(
          content::BrowserContext::GetDownloadManager(profile_))
          ->DownloadPath();

  select_file_dialog_ = ui::SelectFileDialog::Create(
      this,
      std::make_unique<ChromeSelectFilePolicy>(web_ui()->GetWebContents()));
  gfx::NativeWindow owning_window =
      chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())
          ->window()
          ->GetNativeWindow();
  select_file_dialog_->SelectFile(
      ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), downloads_path,
      nullptr, 0, FILE_PATH_LITERAL(""), owning_window, nullptr);
}

void CupsPrintersHandler::ResolveManufacturersDone(
    const std::string& js_callback,
    PpdProvider::CallbackResultCode result_code,
    const std::vector<std::string>& manufacturers) {
  auto manufacturers_value = std::make_unique<base::ListValue>();
  if (result_code == PpdProvider::SUCCESS) {
    manufacturers_value->AppendStrings(manufacturers);
  }
  base::DictionaryValue response;
  response.SetBoolean("success", result_code == PpdProvider::SUCCESS);
  response.Set("manufacturers", std::move(manufacturers_value));
  ResolveJavascriptCallback(base::Value(js_callback), response);
}

void CupsPrintersHandler::ResolvePrintersDone(
    const std::string& manufacturer,
    const std::string& js_callback,
    PpdProvider::CallbackResultCode result_code,
    const PpdProvider::ResolvedPrintersList& printers) {
  auto printers_value = std::make_unique<base::ListValue>();
  if (result_code == PpdProvider::SUCCESS) {
    resolved_printers_[manufacturer] = printers;
    for (const auto& printer : printers) {
      printers_value->AppendString(printer.name);
    }
  }
  base::DictionaryValue response;
  response.SetBoolean("success", result_code == PpdProvider::SUCCESS);
  response.Set("models", std::move(printers_value));
  ResolveJavascriptCallback(base::Value(js_callback), response);
}

void CupsPrintersHandler::FileSelected(const base::FilePath& path,
                                       int index,
                                       void* params) {
  DCHECK(!webui_callback_id_.empty());

  // Load the beggining contents of the file located at |path| and callback into
  // VerifyPpdContents() in order to determine whether the file appears to be a
  // PPD file. The task's priority is USER_BLOCKING because the this task
  // updates the UI as a result of a direct user action.
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
      base::BindOnce(&ReadFileToStringWithMaxSize, path, kPpdMaxLineLength),
      base::BindOnce(&CupsPrintersHandler::VerifyPpdContents,
                     weak_factory_.GetWeakPtr(), path));
}

void CupsPrintersHandler::VerifyPpdContents(const base::FilePath& path,
                                            const std::string& contents) {
  std::string result = "";
  if (PpdLineReader::ContainsMagicNumber(contents, kPpdMaxLineLength))
    result = path.value();

  ResolveJavascriptCallback(base::Value(webui_callback_id_),
                            base::Value(result));
  webui_callback_id_.clear();
}

void CupsPrintersHandler::HandleStartDiscovery(const base::ListValue* args) {
  discovery_active_ = true;
  OnPrintersChanged(
      CupsPrintersManager::kAutomatic,
      printers_manager_->GetPrinters(CupsPrintersManager::kAutomatic));
  OnPrintersChanged(
      CupsPrintersManager::kDiscovered,
      printers_manager_->GetPrinters(CupsPrintersManager::kDiscovered));
  UMA_HISTOGRAM_COUNTS_100(
      "Printing.CUPS.PrintersDiscovered",
      discovered_printers_.size() + automatic_printers_.size());
}

void CupsPrintersHandler::HandleStopDiscovery(const base::ListValue* args) {
  discovered_printers_.clear();
  automatic_printers_.clear();

  // Free up memory while we're not discovering.
  discovered_printers_.shrink_to_fit();
  automatic_printers_.shrink_to_fit();
  discovery_active_ = false;
}

void CupsPrintersHandler::HandleSetUpCancel(const base::ListValue* args) {
  const base::DictionaryValue* printer_dict;
  CHECK(args->GetDictionary(0, &printer_dict));

  std::unique_ptr<Printer> printer = DictToPrinter(*printer_dict);
  if (printer) {
    printers_manager_->RecordSetupAbandoned(*printer);
  }
}

void CupsPrintersHandler::OnPrintersChanged(
    CupsPrintersManager::PrinterClass printer_class,
    const std::vector<Printer>& printers) {
  if (!discovery_active_) {
    return;
  }
  switch (printer_class) {
    case CupsPrintersManager::kAutomatic:
      automatic_printers_ = printers;
      break;
    case CupsPrintersManager::kDiscovered:
      discovered_printers_ = printers;
      break;
    default:
      // It's a class we don't care about.
      return;
  }
  std::unique_ptr<base::ListValue> printers_list =
      std::make_unique<base::ListValue>();
  for (const Printer& printer : automatic_printers_) {
    printers_list->Append(GetPrinterInfo(printer));
  }
  for (const Printer& printer : discovered_printers_) {
    printers_list->Append(GetPrinterInfo(printer));
  }

  FireWebUIListener("on-printer-discovered", *printers_list);
  FireWebUIListener("on-printer-discovery-done");
}

void CupsPrintersHandler::HandleAddDiscoveredPrinter(
    const base::ListValue* args) {
  AllowJavascript();
  CHECK_EQ(1U, args->GetSize());
  std::string printer_id;
  CHECK(args->GetString(0, &printer_id));

  std::unique_ptr<Printer> printer = printers_manager_->GetPrinter(printer_id);
  if (printer == nullptr) {
    // Printer disappeared, so we don't have information about it anymore and
    // can't really do much. Fail the add.
    FireWebUIListener("on-add-cups-printer", base::Value(false),
                      base::Value(printer_id));
    return;
  }

  auto optional = printer->GetUriComponents();
  if (!optional.has_value()) {
    // The printer uri was not parsed successfully. Fail the add.
    FireWebUIListener("on-add-cups-printer", base::Value(false),
                      base::Value(printer_id));
    return;
  }

  if (printer->ppd_reference().autoconf ||
      !printer->ppd_reference().effective_make_and_model.empty() ||
      !printer->ppd_reference().user_supplied_ppd_url.empty()) {
    // If we have something that looks like a ppd reference for this printer,
    // try to configure it.
    printer_configurer_->SetUpPrinter(
        *printer, base::Bind(&CupsPrintersHandler::OnAddedDiscoveredPrinter,
                             weak_factory_.GetWeakPtr(), *printer));
    return;
  }

  // The mDNS record doesn't guarantee we can setup the printer.  Query it to
  // see if we want to try IPP.
  const std::string printer_uri = printer->effective_uri();
  if (IsIppUri(printer_uri)) {
    QueryAutoconf(
        printer_uri,
        base::Bind(&CupsPrintersHandler::OnAutoconfQueriedDiscovered,
                   weak_factory_.GetWeakPtr(), base::Passed(&printer)));
  } else {
    // If it's not an IPP printer, the user must choose a PPD.
    FireWebUIListener("on-manually-add-discovered-printer",
                      *GetPrinterInfo(*printer));
  }
}

void CupsPrintersHandler::HandleGetPrinterPpdManufacturerAndModel(
    const base::ListValue* args) {
  AllowJavascript();
  CHECK_EQ(2U, args->GetSize());
  std::string callback_id;
  CHECK(args->GetString(0, &callback_id));
  std::string printer_id;
  CHECK(args->GetString(1, &printer_id));

  auto printer = printers_manager_->GetPrinter(printer_id);
  if (!printer) {
    RejectJavascriptCallback(base::Value(callback_id), base::Value());
    return;
  }

  ppd_provider_->ReverseLookup(
      printer->ppd_reference().effective_make_and_model,
      base::Bind(&CupsPrintersHandler::OnGetPrinterPpdManufacturerAndModel,
                 weak_factory_.GetWeakPtr(), callback_id));
}

void CupsPrintersHandler::OnGetPrinterPpdManufacturerAndModel(
    const std::string& callback_id,
    PpdProvider::CallbackResultCode result_code,
    const std::string& manufacturer,
    const std::string& model) {
  if (result_code != PpdProvider::SUCCESS) {
    RejectJavascriptCallback(base::Value(callback_id), base::Value());
    return;
  }
  base::DictionaryValue info;
  info.SetString("ppdManufacturer", manufacturer);
  info.SetString("ppdModel", model);
  ResolveJavascriptCallback(base::Value(callback_id), info);
}

}  // namespace settings
}  // namespace chromeos
