// 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 "components/ntp_tiles/webui/ntp_tiles_internals_message_handler.h"

#include <array>
#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/task_runner_util.h"
#include "base/values.h"
#include "components/favicon/core/favicon_service.h"
#include "components/ntp_tiles/most_visited_sites.h"
#include "components/ntp_tiles/pref_names.h"
#include "components/ntp_tiles/webui/ntp_tiles_internals_message_handler_client.h"
#include "components/prefs/pref_service.h"
#include "components/url_formatter/url_fixer.h"
#include "url/gurl.h"

namespace ntp_tiles {

namespace {

using FaviconResultMap = std::map<std::pair<GURL, favicon_base::IconType>,
                                  favicon_base::FaviconRawBitmapResult>;

struct IconTypeAndName {
  favicon_base::IconType type_enum;
  const char* type_name;
};

constexpr std::array<IconTypeAndName, 4> kIconTypesAndNames{{
    {favicon_base::IconType::kFavicon, "kFavicon"},
    {favicon_base::IconType::kTouchIcon, "kTouchIcon"},
    {favicon_base::IconType::kTouchPrecomposedIcon, "kTouchPrecomposedIcon"},
    {favicon_base::IconType::kWebManifestIcon, "kWebManifestIcon"},
}};

std::string FormatJson(const base::Value& value) {
  std::string pretty_printed;
  bool ok = base::JSONWriter::WriteWithOptions(
      value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &pretty_printed);
  DCHECK(ok);
  return pretty_printed;
}

}  // namespace

NTPTilesInternalsMessageHandler::NTPTilesInternalsMessageHandler(
    favicon::FaviconService* favicon_service)
    : favicon_service_(favicon_service),
      client_(nullptr),
      site_count_(8),
      weak_ptr_factory_(this) {}

NTPTilesInternalsMessageHandler::~NTPTilesInternalsMessageHandler() = default;

void NTPTilesInternalsMessageHandler::RegisterMessages(
    NTPTilesInternalsMessageHandlerClient* client) {
  client_ = client;

  client_->RegisterMessageCallback(
      "registerForEvents",
      base::BindRepeating(
          &NTPTilesInternalsMessageHandler::HandleRegisterForEvents,
          base::Unretained(this)));

  client_->RegisterMessageCallback(
      "update",
      base::BindRepeating(&NTPTilesInternalsMessageHandler::HandleUpdate,
                          base::Unretained(this)));

  client_->RegisterMessageCallback(
      "fetchSuggestions",
      base::BindRepeating(
          &NTPTilesInternalsMessageHandler::HandleFetchSuggestions,
          base::Unretained(this)));

  client_->RegisterMessageCallback(
      "viewPopularSitesJson",
      base::BindRepeating(
          &NTPTilesInternalsMessageHandler::HandleViewPopularSitesJson,
          base::Unretained(this)));
}

void NTPTilesInternalsMessageHandler::HandleRegisterForEvents(
    const base::ListValue* args) {
  if (!client_->SupportsNTPTiles()) {
    base::DictionaryValue disabled;
    disabled.SetBoolean("topSites", false);
    disabled.SetBoolean("suggestionsService", false);
    disabled.SetBoolean("popular", false);
    disabled.SetBoolean("whitelist", false);
    client_->CallJavascriptFunction(
        "chrome.ntp_tiles_internals.receiveSourceInfo", disabled);
    SendTiles(NTPTilesVector(), FaviconResultMap());
    return;
  }
  DCHECK(args->empty());

  suggestions_status_.clear();
  popular_sites_json_.clear();
  most_visited_sites_ = client_->MakeMostVisitedSites();
  most_visited_sites_->SetMostVisitedURLsObserver(this, site_count_);
  SendSourceInfo();
}

void NTPTilesInternalsMessageHandler::HandleUpdate(
    const base::ListValue* args) {
  if (!client_->SupportsNTPTiles()) {
    return;
  }

  const base::DictionaryValue* dict = nullptr;
  DCHECK_EQ(1u, args->GetSize());
  args->GetDictionary(0, &dict);
  DCHECK(dict);

  PrefService* prefs = client_->GetPrefs();

  if (most_visited_sites_->DoesSourceExist(ntp_tiles::TileSource::POPULAR)) {
    popular_sites_json_.clear();

    std::string url;
    dict->GetString("popular.overrideURL", &url);
    if (url.empty()) {
      prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideURL);
    } else {
      prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideURL,
                       url_formatter::FixupURL(url, std::string()).spec());
    }

    std::string directory;
    dict->GetString("popular.overrideDirectory", &directory);
    if (directory.empty()) {
      prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideDirectory);
    } else {
      prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideDirectory,
                       directory);
    }

    std::string country;
    dict->GetString("popular.overrideCountry", &country);
    if (country.empty()) {
      prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideCountry);
    } else {
      prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideCountry, country);
    }

    std::string version;
    dict->GetString("popular.overrideVersion", &version);
    if (version.empty()) {
      prefs->ClearPref(ntp_tiles::prefs::kPopularSitesOverrideVersion);
    } else {
      prefs->SetString(ntp_tiles::prefs::kPopularSitesOverrideVersion, version);
    }
  }

  // Recreate to pick up new values.
  // TODO(sfiera): refresh MostVisitedSites without re-creating it, as soon as
  // that will pick up changes to the Popular Sites overrides.
  most_visited_sites_ = client_->MakeMostVisitedSites();
  most_visited_sites_->SetMostVisitedURLsObserver(this, site_count_);
  SendSourceInfo();
}

void NTPTilesInternalsMessageHandler::HandleFetchSuggestions(
    const base::ListValue* args) {
  DCHECK_EQ(0u, args->GetSize());
  if (!most_visited_sites_->DoesSourceExist(
          ntp_tiles::TileSource::SUGGESTIONS_SERVICE)) {
    return;
  }

  if (most_visited_sites_->suggestions()->FetchSuggestionsData()) {
    suggestions_status_ = "fetching...";
  } else {
    suggestions_status_ = "history sync is disabled, or not yet initialized";
  }
  SendSourceInfo();
}

void NTPTilesInternalsMessageHandler::HandleViewPopularSitesJson(
    const base::ListValue* args) {
  DCHECK_EQ(0u, args->GetSize());
  if (!most_visited_sites_->DoesSourceExist(ntp_tiles::TileSource::POPULAR)) {
    return;
  }

  popular_sites_json_ =
      FormatJson(*most_visited_sites_->popular_sites()->GetCachedJson());
  SendSourceInfo();
}

void NTPTilesInternalsMessageHandler::SendSourceInfo() {
  PrefService* prefs = client_->GetPrefs();
  base::DictionaryValue value;

  value.SetBoolean("topSites",
                   most_visited_sites_->DoesSourceExist(TileSource::TOP_SITES));
  value.SetBoolean("whitelist",
                   most_visited_sites_->DoesSourceExist(TileSource::WHITELIST));

  if (most_visited_sites_->DoesSourceExist(TileSource::SUGGESTIONS_SERVICE)) {
    value.SetString("suggestionsService.status", suggestions_status_);
  } else {
    value.SetBoolean("suggestionsService", false);
  }

  if (most_visited_sites_->DoesSourceExist(TileSource::POPULAR)) {
    auto* popular_sites = most_visited_sites_->popular_sites();
    value.SetString("popular.url", popular_sites->GetURLToFetch().spec());
    value.SetString("popular.directory", popular_sites->GetDirectoryToFetch());
    value.SetString("popular.country", popular_sites->GetCountryToFetch());
    value.SetString("popular.version", popular_sites->GetVersionToFetch());

    value.SetString(
        "popular.overrideURL",
        prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL));
    value.SetString(
        "popular.overrideDirectory",
        prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideDirectory));
    value.SetString(
        "popular.overrideCountry",
        prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideCountry));
    value.SetString(
        "popular.overrideVersion",
        prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideVersion));

    value.SetString("popular.json", popular_sites_json_);
  } else {
    value.SetBoolean("popular", false);
  }

  client_->CallJavascriptFunction(
      "chrome.ntp_tiles_internals.receiveSourceInfo", value);
}

void NTPTilesInternalsMessageHandler::SendTiles(
    const NTPTilesVector& tiles,
    const FaviconResultMap& result_map) {
  auto sites_list = std::make_unique<base::ListValue>();
  for (const NTPTile& tile : tiles) {
    auto entry = std::make_unique<base::DictionaryValue>();
    entry->SetString("title", tile.title);
    entry->SetString("url", tile.url.spec());
    entry->SetInteger("source", static_cast<int>(tile.source));
    entry->SetString("whitelistIconPath",
                     tile.whitelist_icon_path.LossyDisplayName());

    auto icon_list = std::make_unique<base::ListValue>();
    for (const auto& entry : kIconTypesAndNames) {
      FaviconResultMap::const_iterator it = result_map.find(
          FaviconResultMap::key_type(tile.url, entry.type_enum));

      if (it != result_map.end()) {
        const favicon_base::FaviconRawBitmapResult& result = it->second;
        auto icon = std::make_unique<base::DictionaryValue>();
        icon->SetString("url", result.icon_url.spec());
        icon->SetString("type", entry.type_name);
        icon->SetBoolean("onDemand", !result.fetched_because_of_page_visit);
        icon->SetInteger("width", result.pixel_size.width());
        icon->SetInteger("height", result.pixel_size.height());
        icon_list->Append(std::move(icon));
      }
    }
    entry->Set("icons", std::move(icon_list));

    sites_list->Append(std::move(entry));
  }

  base::DictionaryValue result;
  result.Set("sites", std::move(sites_list));
  client_->CallJavascriptFunction("chrome.ntp_tiles_internals.receiveSites",
                                  result);
}

void NTPTilesInternalsMessageHandler::OnURLsAvailable(
    const std::map<SectionType, NTPTilesVector>& sections) {
  cancelable_task_tracker_.TryCancelAll();

  // TODO(fhorschig): Handle non-personalized tiles - https://crbug.com/753852.
  const NTPTilesVector& tiles = sections.at(SectionType::PERSONALIZED);
  if (tiles.empty()) {
    SendTiles(tiles, FaviconResultMap());
    return;
  }

  auto on_lookup_done = base::BindRepeating(
      &NTPTilesInternalsMessageHandler::OnFaviconLookupDone,
      // Unretained(this) is safe because of |cancelable_task_tracker_|.
      base::Unretained(this), tiles, base::Owned(new FaviconResultMap()),
      base::Owned(new size_t(tiles.size() * kIconTypesAndNames.size())));

  for (const NTPTile& tile : tiles) {
    for (const auto& entry : kIconTypesAndNames) {
      favicon_service_->GetLargestRawFaviconForPageURL(
          tile.url, std::vector<favicon_base::IconTypeSet>({{entry.type_enum}}),
          /*minimum_size_in_pixels=*/0, base::Bind(on_lookup_done, tile.url),
          &cancelable_task_tracker_);
    }
  }
}

void NTPTilesInternalsMessageHandler::OnIconMadeAvailable(
    const GURL& site_url) {}

void NTPTilesInternalsMessageHandler::OnFaviconLookupDone(
    const NTPTilesVector& tiles,
    FaviconResultMap* result_map,
    size_t* num_pending_lookups,
    const GURL& page_url,
    const favicon_base::FaviconRawBitmapResult& result) {
  DCHECK_NE(0u, *num_pending_lookups);

  result_map->emplace(
      std::pair<GURL, favicon_base::IconType>(page_url, result.icon_type),
      result);

  --*num_pending_lookups;
  if (*num_pending_lookups == 0)
    SendTiles(tiles, *result_map);
}

}  // namespace ntp_tiles
