// 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 "chromeos/printing/ppd_provider.h"

#include <algorithm>
#include <memory>
#include <set>
#include <unordered_map>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/bind_helpers.h"
#include "base/containers/circular_deque.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/json/json_parser.h"
#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chromeos/printing/ppd_cache.h"
#include "chromeos/printing/ppd_line_reader.h"
#include "chromeos/printing/printing_constants.h"
#include "net/base/filename_util.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"

namespace chromeos {
namespace {

// Holds a metadata_v2 reverse-index response
struct ReverseIndexJSON {
  // Canonical name of printer
  std::string effective_make_and_model;

  // Name of printer manufacturer
  std::string manufacturer;

  // Name of printer model
  std::string model;

  // Restrictions for this manufacturer
  PpdProvider::Restrictions restrictions;
};

// Holds a metadata_v2 manufacturers response
struct ManufacturersJSON {
  // Name of printer manufacturer
  std::string name;

  // Key for lookup of this manutacturer's printers (JSON file)
  std::string reference;

  // Restrictions for this manufacturer
  PpdProvider::Restrictions restrictions;
};

// Holds a metadata_v2 printers response
struct PrintersJSON {
  // Name of printer
  std::string name;

  // Canonical name of printer
  std::string effective_make_and_model;

  // Restrictions for this printer
  PpdProvider::Restrictions restrictions;
};

// Holds a metadata_v2 ppd-index response
struct PpdIndexJSON {
  // Canonical name of printer
  std::string effective_make_and_model;

  // Ppd filename
  std::string ppd_filename;
};

// A queued request to download printer information for a manufacturer.
struct PrinterResolutionQueueEntry {
  // Localized manufacturer name
  std::string manufacturer;

  // URL we are going to pull from.
  GURL url;

  // User callback on completion.
  PpdProvider::ResolvePrintersCallback cb;
};

// A queued request to download reverse index information for a make and model
struct ReverseIndexQueueEntry {
  // Canonical Printer Name
  std::string effective_make_and_model;

  // URL we are going to pull from.
  GURL url;

  // User callback on completion.
  PpdProvider::ReverseLookupCallback cb;
};

// Holds manufacturer to printers relation
struct ManufacturerMetadata {
  // Key used to look up the printer list on the server. This is initially
  // populated.
  std::string reference;

  // Map from localized printer name to canonical-make-and-model string for
  // the given printer. Populated on demand.
  std::unique_ptr<std::unordered_map<std::string, PrintersJSON>> printers;
};

// Carried information for an inflight PPD resolution.
struct PpdResolutionQueueEntry {
  // Original reference being resolved.
  Printer::PpdReference reference;

  // If non-empty, the contents from the cache for this resolution.
  std::string cached_contents;

  // Callback to be invoked on completion.
  PpdProvider::ResolvePpdCallback callback;
};

// Extract cupsFilter/cupsFilter2 filter names from a line from a ppd.

// cupsFilter2 lines look like this:
//
// *cupsFilter2: "application/vnd.cups-raster application/vnd.foo 100
// rastertofoo"
//
// cupsFilter lines look like this:
//
// *cupsFilter: "application/vnd.cups-raster 100 rastertofoo"
//
// |field_name| is the starting token we look for (*cupsFilter: or
// *cupsFilter2:).
//
// |num_value_tokens| is the number of tokens we expect to find in the
// value string.  The filter is always the last of these.
//
// Return the name of the filter, if one is found.
//
// This would be simpler with re2, but re2 is not an allowed dependency in
// this part of the tree.
base::Optional<std::string> ExtractCupsFilter(const std::string& line,
                                              const std::string& field_name,
                                              int num_value_tokens) {
  std::string delims(" \n\t\r\"");
  base::StringTokenizer line_tok(line, delims);

  if (!line_tok.GetNext()) {
    return {};
  }
  if (line_tok.token_piece() != field_name) {
    return {};
  }

  // Skip to the last of the value tokens.
  for (int i = 0; i < num_value_tokens; ++i) {
    if (!line_tok.GetNext()) {
      return {};
    }
  }
  if (line_tok.token_piece() != "") {
    return line_tok.token_piece().as_string();
  }
  return {};
}

// Extract the used cups filters from a ppd.
//
// Note that CUPS (post 1.5) discards all cupsFilter lines if *any*
// cupsFilter2 lines exist.
//
std::vector<std::string> ExtractFiltersFromPpd(
    const std::string& ppd_contents) {
  std::string line;
  base::Optional<std::string> tmp;
  auto ppd_reader = PpdLineReader::Create(ppd_contents, 255);
  std::vector<std::string> cups_filters;
  std::vector<std::string> cups_filter2s;
  while (ppd_reader->NextLine(&line)) {
    tmp = ExtractCupsFilter(line, "*cupsFilter:", 3);
    if (tmp.has_value()) {
      cups_filters.push_back(tmp.value());
    }
    tmp = ExtractCupsFilter(line, "*cupsFilter2:", 4);
    if (tmp.has_value()) {
      cups_filter2s.push_back(tmp.value());
    }
  }
  if (!cups_filter2s.empty()) {
    return cups_filter2s;
  }
  return cups_filters;
}

// Returns false if there are obvious errors in the reference that will prevent
// resolution.
bool PpdReferenceIsWellFormed(const Printer::PpdReference& reference) {
  int filled_fields = 0;
  if (!reference.user_supplied_ppd_url.empty()) {
    ++filled_fields;
    GURL tmp_url(reference.user_supplied_ppd_url);
    if (!tmp_url.is_valid() || !tmp_url.SchemeIs("file")) {
      LOG(ERROR) << "Invalid url for a user-supplied ppd: "
                 << reference.user_supplied_ppd_url
                 << " (must be a file:// URL)";
      return false;
    }
  }
  if (!reference.effective_make_and_model.empty()) {
    ++filled_fields;
  }

  // All effective-make-and-model strings should be lowercased, since v2.
  // Since make-and-model strings could include non-Latin chars, only checking
  // that it excludes all upper-case chars A-Z.
  if (!std::all_of(reference.effective_make_and_model.begin(),
                   reference.effective_make_and_model.end(),
                   [](char c) -> bool { return !base::IsAsciiUpper(c); })) {
    return false;
  }
  // Should have exactly one non-empty field.
  return filled_fields == 1;
}

// Fetch the file pointed at by |url| and store it in |file_contents|.
// Returns true if the fetch was successful.
bool FetchFile(const GURL& url, std::string* file_contents) {
  CHECK(url.is_valid());
  CHECK(url.SchemeIs("file"));
  base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);

  // Here we are un-escaping the file path represented by the url. If we don't
  // transform the url into a valid file path then the file may fail to be
  // opened by the system later.
  base::FilePath path;
  if (!net::FileURLToFilePath(url, &path)) {
    LOG(ERROR) << "Not a valid file URL.";
    return false;
  }
  return base::ReadFileToString(path, file_contents);
}

// Constructs and returns a printers' restrictions parsed from |dict|.
PpdProvider::Restrictions ComputeRestrictions(const base::Value& dict) {
  DCHECK(dict.is_dict());
  PpdProvider::Restrictions restrictions;

  const base::Value* min_milestone =
      dict.FindKeyOfType({"min_milestone"}, base::Value::Type::DOUBLE);
  const base::Value* max_milestone =
      dict.FindKeyOfType({"max_milestone"}, base::Value::Type::DOUBLE);

  if (min_milestone) {
    restrictions.min_milestone =
        base::Version(base::NumberToString(min_milestone->GetDouble()));
  }
  if (max_milestone) {
    restrictions.max_milestone =
        base::Version(base::NumberToString(max_milestone->GetDouble()));
  }

  return restrictions;
}

// Returns true if this |printer| is restricted from the
// |current_version|.
bool IsPrinterRestricted(const PrintersJSON& printer,
                         const base::Version& current_version) {
  const PpdProvider::Restrictions& restrictions = printer.restrictions;

  if (restrictions.min_milestone != base::Version("0.0") &&
      restrictions.min_milestone > current_version) {
    return true;
  }

  if (restrictions.max_milestone != base::Version("0.0") &&
      restrictions.max_milestone < current_version) {
    return true;
  }

  return false;
}

// Modifies |printers| by removing any restricted printers excluded from the
// current |version|, as judged by IsPrinterPermitted.
void FilterRestrictedPpdReferences(const base::Version& version,
                                   std::vector<PrintersJSON>* printers) {
  base::EraseIf(*printers, [&version](const PrintersJSON& printer) {
    return IsPrinterRestricted(printer, version);
  });
}

class PpdProviderImpl : public PpdProvider {
 public:
  // What kind of thing is the fetcher currently fetching?  We use this to
  // determine what to do when the fetcher returns a result.
  enum FetcherTarget {
    FT_LOCALES,        // Locales metadata.
    FT_MANUFACTURERS,  // List of manufacturers metadata.
    FT_PRINTERS,       // List of printers from a manufacturer.
    FT_PPD_INDEX,      // Master ppd index.
    FT_PPD,            // A Ppd file.
    FT_REVERSE_INDEX,  // List of sharded printers from a manufacturer
    FT_USB_DEVICES     // USB device id to canonical name map.
  };

  PpdProviderImpl(const std::string& browser_locale,
                  network::mojom::URLLoaderFactory* loader_factory,
                  scoped_refptr<PpdCache> ppd_cache,
                  const base::Version& current_version,
                  const PpdProvider::Options& options)
      : browser_locale_(browser_locale),
        loader_factory_(loader_factory),
        ppd_cache_(ppd_cache),
        disk_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
            {base::TaskPriority::USER_VISIBLE, base::MayBlock(),
             base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
        version_(current_version),
        options_(options),
        weak_factory_(this) {}

  // Resolving manufacturers requires a couple of steps, because of
  // localization.  First we have to figure out what locale to use, which
  // involves grabbing a list of available locales from the server.  Once we
  // have decided on a locale, we go out and fetch the manufacturers map in that
  // localization.
  //
  // This means when a request comes in, we either queue it and start background
  // fetches if necessary, or we satisfy it immediately from memory.
  void ResolveManufacturers(ResolveManufacturersCallback cb) override {
    CHECK(base::SequencedTaskRunnerHandle::IsSet())
        << "ResolveManufacturers must be called from a SequencedTaskRunner"
           "context";
    if (cached_metadata_.get() != nullptr) {
      // We already have this in memory.
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(cb), PpdProvider::SUCCESS,
                                    GetManufacturerList()));
      return;
    }
    manufacturers_resolution_queue_.push_back(std::move(cb));
    MaybeStartFetch();
  }

  // If there are any queued ppd reference resolutions, attempt to make progress
  // on them.  Returns true if a fetch was started, false if no fetch was
  // started.
  bool MaybeStartNextPpdReferenceResolution() {
    while (!ppd_reference_resolution_queue_.empty()) {
      auto& next = ppd_reference_resolution_queue_.front();
      // Have we successfully resolved next yet?
      bool resolved_next = false;
      if (!next.first.make_and_model.empty()) {
        // Check the index for each make-and-model guess.
        for (const std::string& make_and_model : next.first.make_and_model) {
          // Check if we need to load its ppd_index
          int ppd_index_shard = IndexShard(make_and_model);
          if (!base::ContainsKey(cached_ppd_idxs_, ppd_index_shard)) {
            StartFetch(GetPpdIndexURL(ppd_index_shard), FT_PPD_INDEX);
            return true;
          }
          if (base::ContainsKey(cached_ppd_idxs_[ppd_index_shard],
                                make_and_model)) {
            // Found a hit, satisfy this resolution.
            Printer::PpdReference ret;
            ret.effective_make_and_model = make_and_model;
            base::SequencedTaskRunnerHandle::Get()->PostTask(
                FROM_HERE, base::BindOnce(std::move(next.second),
                                          PpdProvider::SUCCESS, ret));
            ppd_reference_resolution_queue_.pop_front();
            resolved_next = true;
            break;
          }
        }
      }
      if (!resolved_next) {
        // If we get to this point, either we don't have any make and model
        // guesses for the front entry, or they all missed.  Try USB ids
        // instead.  This entry will be completed when the usb fetch
        // returns.
        if (next.first.usb_vendor_id && next.first.usb_product_id) {
          StartFetch(GetUsbURL(next.first.usb_vendor_id), FT_USB_DEVICES);
          return true;
        }
        // We don't have anything else left to try.  NOT_FOUND it is.
        base::SequencedTaskRunnerHandle::Get()->PostTask(
            FROM_HERE,
            base::BindOnce(std::move(next.second), PpdProvider::NOT_FOUND,
                           Printer::PpdReference()));
        ppd_reference_resolution_queue_.pop_front();
      }
    }
    // Didn't start any fetches.
    return false;
  }

  // If there is work outstanding that requires a URL fetch to complete, start
  // going on it.
  void MaybeStartFetch() {
    if (fetch_inflight_) {
      // We'll call this again when the outstanding fetch completes.
      return;
    }

    if (MaybeStartNextPpdReferenceResolution()) {
      return;
    }

    if (!manufacturers_resolution_queue_.empty() ||
        !reverse_index_resolution_queue_.empty()) {
      if (locale_.empty()) {
        // Don't have a locale yet, figure that out first.
        StartFetch(GetLocalesURL(), FT_LOCALES);
      } else {
        // Get manufacturers based on the locale we have.
        if (!manufacturers_resolution_queue_.empty()) {
          StartFetch(GetManufacturersURL(locale_), FT_MANUFACTURERS);
        } else if (!reverse_index_resolution_queue_.empty()) {
          // Update the url with the locale before fetching
          ReverseIndexQueueEntry& entry =
              reverse_index_resolution_queue_.front();
          entry.url = GetReverseIndexURL(entry.effective_make_and_model);
          StartFetch(entry.url, FT_REVERSE_INDEX);
        }
      }
      return;
    }
    if (!printers_resolution_queue_.empty()) {
      StartFetch(printers_resolution_queue_.front().url, FT_PRINTERS);
      return;
    }
    while (!ppd_resolution_queue_.empty()) {
      auto& next = ppd_resolution_queue_.front();
      if (!next.reference.user_supplied_ppd_url.empty()) {
        DCHECK(next.reference.effective_make_and_model.empty());
        GURL url(next.reference.user_supplied_ppd_url);
        DCHECK(url.is_valid());
        StartFetch(url, FT_PPD);
        return;
      }
      DCHECK(!next.reference.effective_make_and_model.empty());
      int ppd_index_shard = IndexShard(next.reference.effective_make_and_model);
      if (!base::ContainsKey(cached_ppd_idxs_, ppd_index_shard)) {
        // Have to have the ppd index before we can resolve by ppd server
        // key.
        StartFetch(GetPpdIndexURL(ppd_index_shard), FT_PPD_INDEX);
        return;
      }
      // Get the URL from the ppd index and start the fetch.
      auto& cached_ppd_index = cached_ppd_idxs_[ppd_index_shard];
      auto it = cached_ppd_index.find(next.reference.effective_make_and_model);
      if (it != cached_ppd_index.end()) {
        StartFetch(GetPpdURL(it->second), FT_PPD);
        return;
      }
      // This ppd reference isn't in the index.  That's not good. Fail
      // out the current resolution and go try to start the next
      // thing if there is one.
      LOG(ERROR) << "PPD " << next.reference.effective_make_and_model
                 << " not found in server index";

      FinishPpdResolution(std::move(next.callback), {},
                          PpdProvider::INTERNAL_ERROR);
      ppd_resolution_queue_.pop_front();
    }
  }

  void ResolvePrinters(const std::string& manufacturer,
                       ResolvePrintersCallback cb) override {
    std::unordered_map<std::string, ManufacturerMetadata>::iterator it;
    if (cached_metadata_.get() == nullptr ||
        (it = cached_metadata_->find(manufacturer)) ==
            cached_metadata_->end()) {
      // User error.
      LOG(ERROR) << "Can't resolve printers for unknown manufacturer "
                 << manufacturer;
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(cb), PpdProvider::INTERNAL_ERROR,
                                    ResolvedPrintersList()));
      return;
    }
    if (it->second.printers.get() != nullptr) {
      // Satisfy from the cache.
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(cb), PpdProvider::SUCCESS,
                                    GetManufacturerPrinterList(it->second)));
    } else {
      // We haven't resolved this manufacturer yet.
      PrinterResolutionQueueEntry entry;
      entry.manufacturer = manufacturer;
      entry.url = GetPrintersURL(it->second.reference);
      entry.cb = std::move(cb);
      printers_resolution_queue_.push_back(std::move(entry));
      MaybeStartFetch();
    }
  }

  void ResolvePpdReference(const PrinterSearchData& search_data,
                           ResolvePpdReferenceCallback cb) override {
    // In v2 metadata, we work with lowercased effective_make_and_models.
    PrinterSearchData lowercase_search_data(search_data);
    for (auto& make_and_model : lowercase_search_data.make_and_model) {
      make_and_model = base::ToLowerASCII(make_and_model);
    }

    ppd_reference_resolution_queue_.push_back(
        {lowercase_search_data, std::move(cb)});
    MaybeStartFetch();
  }

  void ResolvePpd(const Printer::PpdReference& reference,
                  ResolvePpdCallback cb) override {
    // In v2 metadata, we work with lowercased effective_make_and_models.
    Printer::PpdReference lowercase_reference(reference);
    lowercase_reference.effective_make_and_model =
        base::ToLowerASCII(lowercase_reference.effective_make_and_model);

    // Do a sanity check here, so we can assume |reference| is well-formed in
    // the rest of this class.
    if (!PpdReferenceIsWellFormed(lowercase_reference)) {
      FinishPpdResolution(std::move(cb), {}, PpdProvider::INTERNAL_ERROR);
      return;
    }

    // First step, check the cache.  If the cache lookup fails, we'll (try to)
    // consult the server.
    ppd_cache_->Find(PpdReferenceToCacheKey(lowercase_reference),
                     base::BindOnce(&PpdProviderImpl::ResolvePpdCacheLookupDone,
                                    weak_factory_.GetWeakPtr(),
                                    lowercase_reference, std::move(cb)));
  }

  void ReverseLookup(const std::string& effective_make_and_model,
                     ReverseLookupCallback cb) override {
    if (effective_make_and_model.empty()) {
      LOG(WARNING) << "Cannot resolve an empty make and model";
      PostReverseLookupFailure(PpdProvider::NOT_FOUND, std::move(cb));
      return;
    }

    // In v2 metadata, we work with lowercased effective_make_and_models.
    std::string lowercase_effective_make_and_model =
        base::ToLowerASCII(effective_make_and_model);

    ReverseIndexQueueEntry entry;
    entry.effective_make_and_model = lowercase_effective_make_and_model;
    entry.url = GetReverseIndexURL(lowercase_effective_make_and_model);
    entry.cb = std::move(cb);
    reverse_index_resolution_queue_.push_back(std::move(entry));
    MaybeStartFetch();
  }

  // Common handler that gets called whenever a fetch completes.  Note this
  // is used both for |fetcher_| fetches (i.e. http[s]) and file-based fetches;
  // |source| may be null in the latter case.
  void OnURLFetchComplete(std::unique_ptr<std::string> body) {
    response_body_ = std::move(body);

    switch (fetcher_target_) {
      case FT_LOCALES:
        OnLocalesFetchComplete();
        break;
      case FT_MANUFACTURERS:
        OnManufacturersFetchComplete();
        break;
      case FT_PRINTERS:
        OnPrintersFetchComplete();
        break;
      case FT_PPD_INDEX:
        OnPpdIndexFetchComplete(fetcher_->GetFinalURL());
        break;
      case FT_PPD:
        OnPpdFetchComplete();
        break;
      case FT_REVERSE_INDEX:
        OnReverseIndexComplete();
        break;
      case FT_USB_DEVICES:
        OnUsbFetchComplete();
        break;
      default:
        LOG(DFATAL) << "Unknown fetch source";
    }
    fetch_inflight_ = false;
    MaybeStartFetch();
  }

 private:
  // Return the URL used to look up the supported locales list.
  GURL GetLocalesURL() {
    return GURL(options_.ppd_server_root + "/metadata_v2/locales.json");
  }

  GURL GetUsbURL(int vendor_id) {
    DCHECK_GT(vendor_id, 0);
    DCHECK_LE(vendor_id, 0xffff);

    return GURL(base::StringPrintf("%s/metadata_v2/usb-%04x.json",
                                   options_.ppd_server_root.c_str(),
                                   vendor_id));
  }

  // Return the URL used to get the |ppd_index_shard| index.
  GURL GetPpdIndexURL(int ppd_index_shard) {
    return GURL(base::StringPrintf("%s/metadata_v2/index-%02d.json",
                                   options_.ppd_server_root.c_str(),
                                   ppd_index_shard));
  }

  // Return the ppd index shard number from its |url|.
  int GetShardFromUrl(const GURL& url) {
    auto url_str = url.spec();
    if (url_str.empty()) {
      return -1;
    }

    // Strip shard number from 2 digits following 'index'
    int idx_pos = url_str.find_first_of("0123456789", url_str.find("index-"));
    return std::stoi(url_str.substr(idx_pos, 2));
  }

  // Return the URL to get a localized manufacturers map.
  GURL GetManufacturersURL(const std::string& locale) {
    return GURL(base::StringPrintf("%s/metadata_v2/manufacturers-%s.json",
                                   options_.ppd_server_root.c_str(),
                                   locale.c_str()));
  }

  // Return the URL used to get a list of printers from the manufacturer |ref|.
  GURL GetPrintersURL(const std::string& ref) {
    return GURL(base::StringPrintf(
        "%s/metadata_v2/%s", options_.ppd_server_root.c_str(), ref.c_str()));
  }

  // Return the URL used to get a ppd with the given filename.
  GURL GetPpdURL(const std::string& filename) {
    return GURL(base::StringPrintf(
        "%s/ppds/%s", options_.ppd_server_root.c_str(), filename.c_str()));
  }

  // Return the URL to get a localized, shared manufacturers map.
  GURL GetReverseIndexURL(const std::string& effective_make_and_model) {
    return GURL(base::StringPrintf("%s/metadata_v2/reverse_index-%s-%02d.json",
                                   options_.ppd_server_root.c_str(),
                                   locale_.c_str(),
                                   IndexShard(effective_make_and_model)));
  }

  // Create and return a fetcher that has the usual (for this class) flags set
  // and calls back to OnURLFetchComplete in this class when it finishes.
  void StartFetch(const GURL& url, FetcherTarget target) {
    DCHECK(!fetch_inflight_);
    DCHECK_EQ(fetcher_.get(), nullptr);
    fetcher_target_ = target;
    fetch_inflight_ = true;

    if (url.SchemeIs("http") || url.SchemeIs("https")) {
      auto resource_request = std::make_unique<network::ResourceRequest>();
      resource_request->url = url;
      resource_request->load_flags =
          net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
          net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES |
          net::LOAD_DO_NOT_SEND_AUTH_DATA;

      // TODO(luum): confirm correct traffic annotation
      fetcher_ = network::SimpleURLLoader::Create(std::move(resource_request),
                                                  MISSING_TRAFFIC_ANNOTATION);

      // TODO(luum): consider using unbounded size
      fetcher_->DownloadToString(
          loader_factory_,
          base::BindOnce(&PpdProviderImpl::OnURLFetchComplete, this),
          network::SimpleURLLoader::kMaxBoundedStringDownloadSize);

    } else if (url.SchemeIs("file")) {
      auto file_contents = std::make_unique<std::string>();
      std::string* content_ptr = file_contents.get();
      base::PostTaskAndReplyWithResult(
          disk_task_runner_.get(), FROM_HERE,
          base::BindOnce(&FetchFile, url, content_ptr),
          base::BindOnce(&PpdProviderImpl::OnFileFetchComplete, this,
                         std::move(file_contents)));
    }
  }

  // Handle the result of a file fetch.
  void OnFileFetchComplete(std::unique_ptr<std::string> file_contents,
                           bool success) {
    file_fetch_success_ = success;
    file_fetch_contents_ = success ? *file_contents : "";
    OnURLFetchComplete(nullptr);
  }

  // Tidy up loose ends on an outstanding PPD resolution.
  //
  // If |ppd_contents| is non-empty, the request is resolved successfully
  // using those contents.  Otherwise |error_code| and an empty ppd
  // is given to |cb|.
  void FinishPpdResolution(ResolvePpdCallback cb,
                           const std::string& ppd_contents,
                           PpdProvider::CallbackResultCode error_code) {
    if (!ppd_contents.empty()) {
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::BindOnce(std::move(cb), PpdProvider::SUCCESS, ppd_contents,
                         ExtractFiltersFromPpd(ppd_contents)));
    } else {
      DCHECK_NE(error_code, PpdProvider::SUCCESS);
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(cb), error_code, std::string(),
                                    std::vector<std::string>()));
    }
  }

  // Callback when the cache lookup for a ppd request finishes.  If we hit in
  // the cache, satisfy the resolution, otherwise kick it over to the fetcher
  // queue to be grabbed from a server.
  void ResolvePpdCacheLookupDone(const Printer::PpdReference& reference,
                                 ResolvePpdCallback cb,
                                 const PpdCache::FindResult& result) {
    // If all of the following are true, we use the cache result now:
    //
    // * It was a cache hit
    // * The reference is not from a user-supplied ppd file
    // * The cached data was fresh.
    //
    // In all other cases, we go through the full resolution flow (passing along
    // the cached data, if we got any), even if we got something from the cache.
    if (result.success && reference.user_supplied_ppd_url.empty() &&
        result.age < options_.cache_staleness_age) {
      DCHECK(!result.contents.empty());
      FinishPpdResolution(std::move(cb), result.contents, PpdProvider::SUCCESS);
    } else {
      // Save the cache result (if any), and queue up for resolution.
      ppd_resolution_queue_.push_back(
          {reference, result.contents, std::move(cb)});
      MaybeStartFetch();
    }
  }

  // Handler for the completion of the locales fetch.  This response should be a
  // list of strings, each of which is a locale in which we can answer queries
  // on the server.  The server (should) guarantee that we get 'en' as an
  // absolute minimum.
  //
  // Combine this information with the browser locale to figure out the best
  // locale to use, and then start a fetch of the manufacturers map in that
  // locale.
  void OnLocalesFetchComplete() {
    std::string contents;
    if (ValidateAndGetResponseAsString(&contents) != PpdProvider::SUCCESS) {
      FailQueuedMetadataResolutions(PpdProvider::SERVER_ERROR);
      return;
    }
    auto top_list = base::ListValue::From(base::JSONReader::Read(contents));

    if (top_list.get() == nullptr) {
      // We got something malformed back.
      FailQueuedMetadataResolutions(PpdProvider::INTERNAL_ERROR);
      return;
    }

    // This should just be a simple list of locale strings.
    std::vector<std::string> available_locales;
    bool found_en = false;
    for (const base::Value& entry : *top_list) {
      std::string tmp;
      // Locales should have at *least* a two-character country code.  100 is an
      // arbitrary upper bound for length to protect against extreme bogosity.
      if (!entry.GetAsString(&tmp) || tmp.size() < 2 || tmp.size() > 100) {
        FailQueuedMetadataResolutions(PpdProvider::INTERNAL_ERROR);
        return;
      }
      if (tmp == "en") {
        found_en = true;
      }
      available_locales.push_back(tmp);
    }
    if (available_locales.empty() || !found_en) {
      // We have no locales, or we didn't get an english locale (which is our
      // ultimate fallback)
      FailQueuedMetadataResolutions(PpdProvider::INTERNAL_ERROR);
      return;
    }
    // Everything checks out, set the locale, head back to fetch dispatch
    // to start the manufacturer fetch.
    locale_ = GetBestLocale(available_locales);
  }

  // Called when the |fetcher_| is expected have the results of a
  // manufacturer map (which maps localized manufacturer names to keys for
  // looking up printers from that manufacturer).  Use this information to
  // populate manufacturer_map_, and resolve all queued ResolveManufacturers()
  // calls.
  void OnManufacturersFetchComplete() {
    DCHECK_EQ(nullptr, cached_metadata_.get());
    std::vector<ManufacturersJSON> contents;
    PpdProvider::CallbackResultCode code =
        ValidateAndParseManufacturersJSON(&contents);
    if (code != PpdProvider::SUCCESS) {
      LOG(ERROR) << "Failed manufacturer parsing";
      FailQueuedMetadataResolutions(code);
      return;
    }
    cached_metadata_ = std::make_unique<
        std::unordered_map<std::string, ManufacturerMetadata>>();

    for (const auto& entry : contents) {
      (*cached_metadata_)[entry.name].reference = entry.reference;
    }

    std::vector<std::string> manufacturer_list = GetManufacturerList();
    // Complete any queued manufacturer resolutions.
    for (auto& cb : manufacturers_resolution_queue_) {
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(cb), PpdProvider::SUCCESS,
                                    manufacturer_list));
    }
    manufacturers_resolution_queue_.clear();
  }

  // The outstanding fetch associated with the front of
  // |printers_resolution_queue_| finished, use the response to satisfy that
  // ResolvePrinters() call.
  void OnPrintersFetchComplete() {
    CHECK(cached_metadata_.get() != nullptr);
    DCHECK(!printers_resolution_queue_.empty());
    std::vector<PrintersJSON> contents;

    PpdProvider::CallbackResultCode code =
        ValidateAndParsePrintersJSON(&contents);

    if (code != PpdProvider::SUCCESS) {
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::BindOnce(std::move(printers_resolution_queue_.front().cb), code,
                         ResolvedPrintersList()));
    } else {
      // This should be a list of lists of 2-element strings, where the first
      // element is the localized name of the printer and the second element
      // is the canonical name of the printer.
      const std::string& manufacturer =
          printers_resolution_queue_.front().manufacturer;
      auto it = cached_metadata_->find(manufacturer);

      // If we kicked off a resolution, the entry better have already been
      // in the map.
      CHECK(it != cached_metadata_->end());

      // Create the printer map in the cache, and populate it.
      auto& manufacturer_metadata = it->second;
      CHECK(manufacturer_metadata.printers.get() == nullptr);
      manufacturer_metadata.printers =
          std::make_unique<std::unordered_map<std::string, PrintersJSON>>();

      for (const auto& entry : contents) {
        manufacturer_metadata.printers->insert({entry.name, entry});
      }

      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::BindOnce(std::move(printers_resolution_queue_.front().cb),
                         PpdProvider::SUCCESS,
                         GetManufacturerPrinterList(manufacturer_metadata)));
    }
    printers_resolution_queue_.pop_front();
  }

  // Called when |fetcher_| should have just received an index mapping
  // ppd server keys to ppd filenames.  Use this to populate
  // |cached_ppd_idxs_|.
  void OnPpdIndexFetchComplete(GURL url) {
    std::vector<PpdIndexJSON> contents;
    PpdProvider::CallbackResultCode code =
        ValidateAndParsePpdIndexJSON(&contents);
    if (code != PpdProvider::SUCCESS) {
      FailQueuedServerPpdResolutions(code);
    } else {
      int ppd_index_shard = GetShardFromUrl(url);
      if (ppd_index_shard < 0) {
        FailQueuedServerPpdResolutions(PpdProvider::INTERNAL_ERROR);
        return;
      }
      auto& cached_ppd_index = cached_ppd_idxs_[ppd_index_shard];
      for (const auto& entry : contents) {
        cached_ppd_index.insert(
            {entry.effective_make_and_model, entry.ppd_filename});
      }
    }
  }

  // This is called when |fetcher_| should have just downloaded a ppd.  If we
  // downloaded something successfully, use it to satisfy the front of the ppd
  // resolution queue, otherwise fail out that resolution.
  void OnPpdFetchComplete() {
    DCHECK(!ppd_resolution_queue_.empty());
    std::string contents;
    auto& entry = ppd_resolution_queue_.front();
    if ((ValidateAndGetResponseAsString(&contents) != PpdProvider::SUCCESS)) {
      FinishPpdResolution(std::move(entry.callback), entry.cached_contents,
                          PpdProvider::SERVER_ERROR);
    } else if (contents.size() > kMaxPpdSizeBytes) {
      FinishPpdResolution(std::move(entry.callback), entry.cached_contents,
                          PpdProvider::PPD_TOO_LARGE);
    } else if (contents.empty()) {
      FinishPpdResolution(std::move(entry.callback), entry.cached_contents,
                          PpdProvider::INTERNAL_ERROR);
    } else {
      // Success.  Cache it and return it to the user.
      ppd_cache_->Store(
          PpdReferenceToCacheKey(ppd_resolution_queue_.front().reference),
          contents);
      FinishPpdResolution(std::move(entry.callback), contents,
                          PpdProvider::SUCCESS);
    }
    ppd_resolution_queue_.pop_front();
  }

  // This is called when |fetch_| should have just downloaded a reverse index
  // file. If we downloaded something successfully, used the downloaded results
  // to satisfy the callback in the first item of the reverse index resolution
  // queue.
  void OnReverseIndexComplete() {
    DCHECK(!reverse_index_resolution_queue_.empty());
    std::vector<ReverseIndexJSON> contents;
    PpdProvider::CallbackResultCode code =
        ValidateAndParseReverseIndexJSON(&contents);
    auto& entry = reverse_index_resolution_queue_.front();

    if (code != PpdProvider::SUCCESS) {
      LOG(ERROR) << "Request Failed or failed reverse index parsing";
      PostReverseLookupFailure(code, std::move(entry.cb));
    } else {
      auto found = std::find_if(contents.begin(), contents.end(),
                                [&entry](const ReverseIndexJSON& rij) -> bool {
                                  return rij.effective_make_and_model ==
                                         entry.effective_make_and_model;
                                });
      if (found != contents.end()) {
        base::SequencedTaskRunnerHandle::Get()->PostTask(
            FROM_HERE, base::BindOnce(std::move(entry.cb), PpdProvider::SUCCESS,
                                      found->manufacturer, found->model));
      } else {
        LOG(ERROR) << "Failed to lookup printer in retrieved data response";
        PostReverseLookupFailure(PpdProvider::NOT_FOUND, std::move(entry.cb));
      }
    }
    reverse_index_resolution_queue_.pop_front();
  }

  // Called when |fetcher_| should have just downloaded a usb device map
  // for the vendor at the head of the |ppd_reference_resolution_queue_|.
  void OnUsbFetchComplete() {
    DCHECK(!ppd_reference_resolution_queue_.empty());
    std::string contents;
    std::string buffer;
    PpdProvider::CallbackResultCode result =
        ValidateAndGetResponseAsString(&buffer);
    int desired_device_id =
        ppd_reference_resolution_queue_.front().first.usb_product_id;
    if (result == PpdProvider::SUCCESS) {
      // Parse the JSON response.  This should be a list of the form
      // [
      //  [0x3141, "some canonical name"],
      //  [0x5926, "some othercanonical name"]
      // ]
      // So we scan through the response looking for our desired device id.
      auto top_list = base::ListValue::From(base::JSONReader::Read(buffer));

      if (top_list.get() == nullptr) {
        // We got something malformed back.
        LOG(ERROR) << "Malformed top list";
        result = PpdProvider::INTERNAL_ERROR;
      } else {
        // We'll set result to SUCCESS if we do find the device.
        result = PpdProvider::NOT_FOUND;
        for (const auto& entry : *top_list) {
          int device_id;
          const base::ListValue* sub_list;

          // Each entry should be a size-2 list with an integer and a string.
          if (!entry.GetAsList(&sub_list) || sub_list->GetSize() != 2 ||
              !sub_list->GetInteger(0, &device_id) ||
              !sub_list->GetString(1, &contents) || device_id < 0 ||
              device_id > 0xffff) {
            // Malformed data.
            LOG(ERROR) << "Malformed line in usb device list";
            result = PpdProvider::INTERNAL_ERROR;
            break;
          }
          if (device_id == desired_device_id) {
            // Found it.
            result = PpdProvider::SUCCESS;
            break;
          }
        }
      }
    }
    Printer::PpdReference ret;
    if (result == PpdProvider::SUCCESS) {
      ret.effective_make_and_model = contents;
    }
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(
            std::move(ppd_reference_resolution_queue_.front().second), result,
            ret));
    ppd_reference_resolution_queue_.pop_front();
  }

  // Something went wrong during metadata fetches.  Fail all queued metadata
  // resolutions with the given error code.
  void FailQueuedMetadataResolutions(PpdProvider::CallbackResultCode code) {
    for (auto& cb : manufacturers_resolution_queue_) {
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::BindOnce(std::move(cb), code, std::vector<std::string>()));
    }
    manufacturers_resolution_queue_.clear();
  }

  // Give up on all server-based ppd and ppd reference resolutions inflight,
  // because we failed to grab the necessary index data from the server.
  //
  // User-based ppd resolutions, which depend on local files, are left in the
  // queue.
  //
  // Other entries use cached data, if they found some, or failed outright.
  void FailQueuedServerPpdResolutions(PpdProvider::CallbackResultCode code) {
    base::circular_deque<PpdResolutionQueueEntry> filtered_queue;
    for (auto& entry : ppd_resolution_queue_) {
      if (!entry.reference.user_supplied_ppd_url.empty()) {
        filtered_queue.emplace_back(std::move(entry));
      } else {
        FinishPpdResolution(std::move(entry.callback), entry.cached_contents,
                            code);
      }
    }
    ppd_resolution_queue_ = std::move(filtered_queue);

    // Everything in the PpdReference queue also depends on server information,
    // so should also be failed.
    auto task_runner = base::SequencedTaskRunnerHandle::Get();
    for (auto& cb : ppd_reference_resolution_queue_) {
      task_runner->PostTask(
          FROM_HERE,
          base::BindOnce(std::move(cb.second), code, Printer::PpdReference()));
    }
    ppd_reference_resolution_queue_.clear();
  }

  // Given a list of possible locale strings (e.g. 'en-GB'), determine which of
  // them we should use to best serve results for the browser locale (which was
  // given to us at construction time).
  std::string GetBestLocale(const std::vector<std::string>& available_locales) {
    // First look for an exact match.  If we find one, just use that.
    for (const std::string& available : available_locales) {
      if (available == browser_locale_) {
        return available;
      }
    }

    // Next, look for an available locale that is a parent of browser_locale_.
    // Return the most specific one.  For example, if we want 'en-GB-foo' and we
    // don't have an exact match, but we do have 'en-GB' and 'en', we will
    // return 'en-GB' -- the most specific match which is a parent of the
    // requested locale.
    size_t best_len = 0;
    size_t best_idx = -1;
    for (size_t i = 0; i < available_locales.size(); ++i) {
      const std::string& available = available_locales[i];
      if (base::StringPiece(browser_locale_).starts_with(available + "-") &&
          available.size() > best_len) {
        best_len = available.size();
        best_idx = i;
      }
    }
    if (best_idx != static_cast<size_t>(-1)) {
      return available_locales[best_idx];
    }

    // Last chance for a match, look for the locale that matches the *most*
    // pieces of locale_, with ties broken by being least specific.  So for
    // example, if we have 'es-GB', 'es-GB-foo' but no 'es' available, and we're
    // requesting something for 'es', we'll get back 'es-GB' -- the least
    // specific thing that matches some of the locale.
    std::vector<base::StringPiece> browser_locale_pieces =
        base::SplitStringPiece(browser_locale_, "-", base::KEEP_WHITESPACE,
                               base::SPLIT_WANT_ALL);
    size_t best_match_size = 0;
    size_t best_match_specificity;
    best_idx = -1;
    for (size_t i = 0; i < available_locales.size(); ++i) {
      const std::string& available = available_locales[i];
      std::vector<base::StringPiece> available_pieces = base::SplitStringPiece(
          available, "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
      size_t match_size = 0;
      for (; match_size < available_pieces.size() &&
             match_size < browser_locale_pieces.size();
           ++match_size) {
        if (available_pieces[match_size] != browser_locale_pieces[match_size]) {
          break;
        }
      }
      if (match_size > 0 &&
          (best_idx == static_cast<size_t>(-1) ||
           match_size > best_match_size ||
           (match_size == best_match_size &&
            available_pieces.size() < best_match_specificity))) {
        best_idx = i;
        best_match_size = match_size;
        best_match_specificity = available_pieces.size();
      }
    }
    if (best_idx != static_cast<size_t>(-1)) {
      return available_locales[best_idx];
    }

    // Everything else failed.  Throw up our hands and default to english.
    return "en";
  }

  // Get the results of a fetch.  This is a little tricky, because a fetch
  // may have been done by |fetcher_|, or it may have been a file access, in
  // which case we want to look at |file_fetch_contents_|.  We distinguish
  // between the cases based on whether or not |fetcher_| is null.
  //
  // We return NOT_FOUND for 404 or file not found, SERVER_ERROR for other
  // errors, SUCCESS if everything was good.
  CallbackResultCode ValidateAndGetResponseAsString(std::string* contents) {
    CallbackResultCode ret;
    if (fetcher_.get() != nullptr) {
      if (response_body_.get() == nullptr) {
        ret = PpdProvider::SERVER_ERROR;
      } else if (fetcher_->NetError() != 0) {
        // TODO(luum): confirm netError != 0 behavior === 404 not found
        ret = PpdProvider::SERVER_ERROR;
      } else {
        *contents = std::move(*response_body_);
        ret = PpdProvider::SUCCESS;
      }
      fetcher_.reset();
    } else {
      // It's a file load.
      if (file_fetch_success_) {
        *contents = file_fetch_contents_;
      } else {
        contents->clear();
      }
      // A failure to load a file is always considered a NOT FOUND error (even
      // if the underlying causes is lack of access or similar, this seems to be
      // the best match for intent.
      ret = file_fetch_success_ ? PpdProvider::SUCCESS : PpdProvider::NOT_FOUND;
      file_fetch_contents_.clear();
    }
    return ret;
  }

  // Ensures that the fetched JSON is in the expected format, that is leading
  // with exactly |num_strings| and followed by an optional dictionary. Returns
  // PpdProvider::SUCCESS and saves JSON list in |top_list| if format is valid,
  // returns PpdProvider::INTERNAL_ERROR otherwise.
  PpdProvider::CallbackResultCode ParseAndValidateJSONFormat(
      base::Value::ListStorage* top_list,
      size_t num_strings) {
    std::string buffer;

    auto fetch_result = ValidateAndGetResponseAsString(&buffer);
    if (fetch_result != PpdProvider::SUCCESS) {
      return fetch_result;
    }

    auto ret_list = base::ListValue::From(base::JSONReader::Read(buffer));
    if (ret_list == nullptr) {
      return PpdProvider::INTERNAL_ERROR;
    }
    *top_list = std::move(ret_list->GetList());

    for (const auto& entry : *top_list) {
      if (!entry.is_list()) {
        return PpdProvider::INTERNAL_ERROR;
      }

      // entry must start with |num_strings| strings
      const base::Value::ListStorage& list = entry.GetList();
      if (list.size() < num_strings) {
        return PpdProvider::INTERNAL_ERROR;
      }
      for (size_t i = 0; i < num_strings; ++i) {
        if (!list[i].is_string()) {
          return PpdProvider::INTERNAL_ERROR;
        }
      }

      // entry may optionally have a last arg that must be a dict
      if (list.size() > num_strings && !list[num_strings].is_dict()) {
        return PpdProvider::INTERNAL_ERROR;
      }

      // entry may not have more than |num_strings| strings and one dict
      if (list.size() > num_strings + 1) {
        return PpdProvider::INTERNAL_ERROR;
      }
    }

    return PpdProvider::SUCCESS;
  }

  // Attempts to parse a ReverseIndexJSON reply to |fetcher| into the passed
  // contents. Returns PpdProvider::SUCCESS on valid JSON formatting and filled
  // |contents|, clears |contents| otherwise.
  PpdProvider::CallbackResultCode ValidateAndParseReverseIndexJSON(
      std::vector<ReverseIndexJSON>* contents) {
    DCHECK(contents != nullptr);
    contents->clear();

    base::Value::ListStorage top_list;
    auto ret = ParseAndValidateJSONFormat(&top_list, 3);
    if (ret != PpdProvider::SUCCESS) {
      LOG(ERROR) << "Failed to parse ReverseIndex metadata";
      return ret;
    }

    // Fetched data should be in the form {[effective_make_and_model],
    // [manufacturer], [model], [dictionary of metadata]}
    for (const auto& entry : top_list) {
      const base::Value::ListStorage& list = entry.GetList();

      ReverseIndexJSON rij_entry;
      rij_entry.effective_make_and_model = list[0].GetString();
      rij_entry.manufacturer = list[1].GetString();
      rij_entry.model = list[2].GetString();

      // Populate restrictions, if available
      if (list.size() > 3) {
        rij_entry.restrictions = ComputeRestrictions(list[3]);
      }

      contents->push_back(rij_entry);
    }
    return PpdProvider::SUCCESS;
  }

  // Attempts to parse a ManufacturersJSON reply to |fetcher| into the passed
  // contents. Returns PpdProvider::SUCCESS on valid JSON formatting and filled
  // |contents|, clears |contents| otherwise.
  PpdProvider::CallbackResultCode ValidateAndParseManufacturersJSON(
      std::vector<ManufacturersJSON>* contents) {
    DCHECK(contents != NULL);
    contents->clear();

    base::Value::ListStorage top_list;
    auto ret = ParseAndValidateJSONFormat(&top_list, 2);
    if (ret != PpdProvider::SUCCESS) {
      LOG(ERROR) << "Failed to process Manufacturers metadata";
      return ret;
    }

    // Fetched data should be in form [[name], [canonical name],
    // {restrictions}]
    for (const auto& entry : top_list) {
      const base::Value::ListStorage& list = entry.GetList();
      ManufacturersJSON mj_entry;
      mj_entry.name = list[0].GetString();
      mj_entry.reference = list[1].GetString();

      // Populate restrictions, if available
      if (list.size() > 2) {
        mj_entry.restrictions = ComputeRestrictions(list[2]);
      }

      contents->push_back(mj_entry);
    }

    return PpdProvider::SUCCESS;
  }

  // Attempts to parse a PrintersJSON reply to |fetcher| into the passed
  // contents. Returns PpdProvider::SUCCESS on valid JSON formatting and filled
  // |contents|, clears |contents| otherwise.
  PpdProvider::CallbackResultCode ValidateAndParsePrintersJSON(
      std::vector<PrintersJSON>* contents) {
    DCHECK(contents != NULL);
    contents->clear();

    base::Value::ListStorage top_list;
    auto ret = ParseAndValidateJSONFormat(&top_list, 2);
    if (ret != PpdProvider::SUCCESS) {
      LOG(ERROR) << "Failed to parse Printers metadata";
      return ret;
    }

    // Fetched data should be in form [[name], [canonical name],
    // {restrictions}]
    for (const auto& entry : top_list) {
      const base::Value::ListStorage& list = entry.GetList();
      PrintersJSON pj_entry;
      pj_entry.name = list[0].GetString();
      pj_entry.effective_make_and_model = list[1].GetString();

      // Populate restrictions, if available
      if (list.size() > 2) {
        pj_entry.restrictions = ComputeRestrictions(list[2]);
      }

      contents->push_back(pj_entry);
    }

    return PpdProvider::SUCCESS;
  }

  // Attempts to parse a PpdIndexJSON reply to |fetcher| into the passed
  // contents. Returns PpdProvider::SUCCESS on valid JSON formatting and filled
  // |contents|, clears |contents| otherwise.
  PpdProvider::CallbackResultCode ValidateAndParsePpdIndexJSON(
      std::vector<PpdIndexJSON>* contents) {
    DCHECK(contents != nullptr);
    contents->clear();

    base::Value::ListStorage top_list;
    auto ret = ParseAndValidateJSONFormat(&top_list, 2);
    if (ret != PpdProvider::SUCCESS) {
      LOG(ERROR) << "Failed to parse PpdIndex metadata";
      return ret;
    }

    // Fetched data should be in the form {[effective_make_and_model],
    // [manufacturer], [model], [dictionary of metadata]}
    for (const auto& entry : top_list) {
      const base::Value::ListStorage& list = entry.GetList();

      PpdIndexJSON pij_entry;
      pij_entry.effective_make_and_model = list[0].GetString();
      pij_entry.ppd_filename = list[1].GetString();

      contents->push_back(pij_entry);
    }
    return PpdProvider::SUCCESS;
  }

  // Create the list of manufacturers from |cached_metadata_|.  Requires that
  // the manufacturer list has already been resolved.
  std::vector<std::string> GetManufacturerList() const {
    CHECK(cached_metadata_.get() != nullptr);
    std::vector<std::string> ret;
    ret.reserve(cached_metadata_->size());
    for (const auto& entry : *cached_metadata_) {
      ret.push_back(entry.first);
    }
    // TODO(justincarlson) -- this should be a localization-aware sort.
    sort(ret.begin(), ret.end());
    return ret;
  }

  // Get the list of printers from a given manufacturer from |cached_metadata_|.
  // Requires that we have already resolved this from the server.
  ResolvedPrintersList GetManufacturerPrinterList(
      const ManufacturerMetadata& meta) const {
    CHECK(meta.printers.get() != nullptr);
    std::vector<PrintersJSON> printers;
    printers.reserve(meta.printers->size());
    for (const auto& entry : *meta.printers) {
      printers.push_back(entry.second);
    }
    // TODO(justincarlson) -- this should be a localization-aware sort.
    sort(printers.begin(), printers.end(),
         [](const PrintersJSON& a, const PrintersJSON& b) -> bool {
           return a.name < b.name;
         });
    FilterRestrictedPpdReferences(version_, &printers);

    ResolvedPrintersList ret;
    ret.reserve(printers.size());
    for (const auto& printer : printers) {
      Printer::PpdReference ppd_ref;
      ppd_ref.effective_make_and_model = printer.effective_make_and_model;
      ret.push_back({printer.name, ppd_ref});
    }
    return ret;
  }

  void PostReverseLookupFailure(CallbackResultCode result,
                                ReverseLookupCallback cb) {
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(cb), result, std::string(), std::string()));
  }

  // The hash function to calculate the hash of canonical identifiers to the
  // name of the ppd file for that printer.
  int IndexShard(std::string effective_make_and_model) {
    unsigned int hash = 5381;
    int kNumIndexShards = 20;

    for (char c : effective_make_and_model) {
      hash = hash * 33 + c;
    }
    return hash % kNumIndexShards;
  }

  // Map from (localized) manufacturer name to metadata for that manufacturer.
  // This is populated lazily.  If we don't yet have a manufacturer list, the
  // top pointer will be null.  When we create the top level map, then each
  // value will only contain a reference which can be used to resolve the
  // printer list from that manufacturer.  On demand, we use these references to
  // resolve the actual printer lists.
  std::unique_ptr<std::unordered_map<std::string, ManufacturerMetadata>>
      cached_metadata_;

  // Cached contents of the server indexs, which maps first a shard number to
  // the corresponding index map of PpdReference::effective_make_and_models to a
  // urls for the corresponding ppds. Starts as an empty map and filled lazily
  // as we need to fill in more indexs.
  std::unordered_map<int, std::unordered_map<std::string, std::string>>
      cached_ppd_idxs_;

  // Queued ResolveManufacturers() calls.  We will simultaneously resolve
  // all queued requests, so no need for a deque here.
  std::vector<ResolveManufacturersCallback> manufacturers_resolution_queue_;

  // Queued ResolvePrinters() calls.
  base::circular_deque<PrinterResolutionQueueEntry> printers_resolution_queue_;

  // Queued ResolvePpd() requests.
  base::circular_deque<PpdResolutionQueueEntry> ppd_resolution_queue_;

  // Queued ResolvePpdReference() requests.
  base::circular_deque<
      std::pair<PrinterSearchData, ResolvePpdReferenceCallback>>
      ppd_reference_resolution_queue_;

  // Queued ReverseIndex() calls.
  base::circular_deque<ReverseIndexQueueEntry> reverse_index_resolution_queue_;

  // Locale we're using for grabbing stuff from the server.  Empty if we haven't
  // determined it yet.
  std::string locale_;

  // If the fetcher is active, what's it fetching?
  FetcherTarget fetcher_target_;

  // Fetcher used for all network fetches.  This is explicitly reset() when
  // a fetch has been processed.
  std::unique_ptr<network::SimpleURLLoader> fetcher_;
  bool fetch_inflight_ = false;
  std::unique_ptr<std::string> response_body_;

  // Locale of the browser, as returned by
  // BrowserContext::GetApplicationLocale();
  const std::string browser_locale_;

  network::mojom::URLLoaderFactory* loader_factory_;

  // For file:// fetches, a staging buffer and result flag for loading the file.
  std::string file_fetch_contents_;
  bool file_fetch_success_;

  // Cache of ppd files.
  scoped_refptr<PpdCache> ppd_cache_;

  // Where to run disk operations.
  scoped_refptr<base::SequencedTaskRunner> disk_task_runner_;

  // Current version used to filter restricted ppds
  base::Version version_;

  // Construction-time options, immutable.
  const PpdProvider::Options options_;

  base::WeakPtrFactory<PpdProviderImpl> weak_factory_;

 protected:
  ~PpdProviderImpl() override = default;
};

}  // namespace

// static
std::string PpdProvider::PpdReferenceToCacheKey(
    const Printer::PpdReference& reference) {
  DCHECK(PpdReferenceIsWellFormed(reference));
  // The key prefixes here are arbitrary, but ensure we can't have an (unhashed)
  // collision between keys generated from different PpdReference fields.
  if (!reference.effective_make_and_model.empty()) {
    return std::string("em:") + reference.effective_make_and_model;
  } else {
    return std::string("up:") + reference.user_supplied_ppd_url;
  }
}

PpdProvider::PrinterSearchData::PrinterSearchData() = default;
PpdProvider::PrinterSearchData::PrinterSearchData(
    const PrinterSearchData& other) = default;
PpdProvider::PrinterSearchData::~PrinterSearchData() = default;

// static
scoped_refptr<PpdProvider> PpdProvider::Create(
    const std::string& browser_locale,
    network::mojom::URLLoaderFactory* loader_factory,
    scoped_refptr<PpdCache> ppd_cache,
    const base::Version& current_version,
    const PpdProvider::Options& options) {
  return scoped_refptr<PpdProvider>(new PpdProviderImpl(
      browser_locale, loader_factory, ppd_cache, current_version, options));
}
}  // namespace chromeos
