// Copyright 2014 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/font_family_cache.h"

#include <stddef.h>

#include <map>

#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/font_pref_change_notifier_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_font_webkit_names.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/notification_source.h"

// Identifies the user data on the profile.
const char kFontFamilyCacheKey[] = "FontFamilyCacheKey";

FontFamilyCache::FontFamilyCache(Profile* profile)
    : prefs_(profile->GetPrefs()) {
  notification_registrar_.Add(this,
                              chrome::NOTIFICATION_PROFILE_DESTROYED,
                              content::Source<Profile>(profile));

  // Safe to use Unretained here since the registrar is scoped to this class.
  font_change_registrar_.Register(
      FontPrefChangeNotifierFactory::GetForProfile(profile),
      base::Bind(&FontFamilyCache::OnPrefsChanged, base::Unretained(this)));
}

FontFamilyCache::~FontFamilyCache() {
}

void FontFamilyCache::FillFontFamilyMap(Profile* profile,
                                        const char* map_name,
                                        content::ScriptFontFamilyMap* map) {
  FontFamilyCache* cache =
      static_cast<FontFamilyCache*>(profile->GetUserData(&kFontFamilyCacheKey));
  if (!cache) {
    cache = new FontFamilyCache(profile);
    profile->SetUserData(&kFontFamilyCacheKey, base::WrapUnique(cache));
  }

  cache->FillFontFamilyMap(map_name, map);
}

void FontFamilyCache::FillFontFamilyMap(const char* map_name,
                                        content::ScriptFontFamilyMap* map) {
  // TODO(falken): Get rid of the brute-force scan over possible
  // (font family / script) combinations - see http://crbug.com/308095.
  for (size_t i = 0; i < prefs::kWebKitScriptsForFontFamilyMapsLength; ++i) {
    const char* script = prefs::kWebKitScriptsForFontFamilyMaps[i];
    base::string16 result = FetchAndCacheFont(script, map_name);
    if (!result.empty())
      (*map)[script] = result;
  }
}

base::string16 FontFamilyCache::FetchFont(const char* script,
                                          const char* map_name) {
  std::string pref_name = base::StringPrintf("%s.%s", map_name, script);
  std::string font = prefs_->GetString(pref_name.c_str());
  base::string16 font16 = base::UTF8ToUTF16(font);

  // Lazily constructs the map if it doesn't already exist.
  ScriptFontMap& map = font_family_map_[map_name];
  map[script] = font16;
  return font16;
}

base::string16 FontFamilyCache::FetchAndCacheFont(const char* script,
                                                  const char* map_name) {
  FontFamilyMap::const_iterator it = font_family_map_.find(map_name);
  if (it != font_family_map_.end()) {
    auto it2 = it->second.find(script);
    if (it2 != it->second.end())
      return it2->second;
  }

  return FetchFont(script, map_name);
}

// There are ~1000 entries in the cache. Avoid unnecessary object construction,
// including std::string.
void FontFamilyCache::OnPrefsChanged(const std::string& pref_name) {
  const size_t delimiter_length = 1;
  const char delimiter = '.';
  for (auto& it : font_family_map_) {
    const char* map_name = it.first;
    size_t map_name_length = strlen(map_name);

    // If the map name doesn't match, move on.
    if (pref_name.compare(0, map_name_length, map_name) != 0)
      continue;

    ScriptFontMap& map = it.second;
    for (auto it2 = map.begin(); it2 != map.end(); ++it2) {
      const char* script = it2->first;
      size_t script_length = strlen(script);

      // If the length doesn't match, move on.
      if (pref_name.size() !=
          map_name_length + script_length + delimiter_length)
        continue;

      // If the script doesn't match, move on.
      if (pref_name.compare(
              map_name_length + delimiter_length, script_length, script) != 0)
        continue;

      // If the delimiter doesn't match, move on.
      if (pref_name[map_name_length] != delimiter)
        continue;

      // Clear the cache.
      map.erase(it2);
      break;
    }
  }
}

void FontFamilyCache::Observe(int type,
                              const content::NotificationSource& source,
                              const content::NotificationDetails& details) {
  DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type);
  font_change_registrar_.Unregister();
}
