// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_DOM_FONT_CACHE_H_
#define COBALT_DOM_FONT_CACHE_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>

#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "cobalt/dom/font_face.h"
#include "cobalt/dom/font_list.h"
#include "cobalt/dom/location.h"
#include "cobalt/loader/font/remote_typeface_cache.h"
#include "cobalt/render_tree/font.h"
#include "cobalt/render_tree/glyph.h"
#include "cobalt/render_tree/resource_provider.h"
#include "url/gurl.h"

namespace cobalt {
namespace dom {

// The font cache is typically owned by dom::Document and handles the following:
//   - Tracking of font faces, which it uses to determine if a specified
//     font family is local or remote, and for url determination in requesting
//     remote typefaces.
//   - Creation and caching of font lists, which it provides to the used
//     style provider as requested. Font lists handle most layout-related font
//     cache interactions. Layout objects only interact with the font cache
//     through their font lists.
//   - Retrieval of typefaces, either locally from the resource provider or
//     remotely from the remote typeface cache, and caching of both typefaces
//     and fonts to facilitate sharing of them across font lists.
//   - Determination of the fallback typeface for a specific character using a
//     specific font style, and caching of that information for subsequent
//     lookups.
//   - Creation of glyph buffers, which is accomplished by passing the request
//    to the resource provider.
// NOTE: The font cache is not thread-safe and must only used within a single
// thread.
class FontCache {
 public:
  class RequestedRemoteTypefaceInfo
      : public base::RefCounted<RequestedRemoteTypefaceInfo> {
   public:
    RequestedRemoteTypefaceInfo(
        const scoped_refptr<loader::font::CachedRemoteTypeface>&
            cached_remote_typeface,
        const base::Closure& font_load_event_callback);

    bool HasActiveRequestTimer() const { return request_timer_ != NULL; }
    void ClearRequestTimer() { request_timer_.reset(); }

   private:
    // The request timer delay, after which the requesting font list's fallback
    // font becomes visible.
    // NOTE: While using a timer of exactly 3 seconds is not specified by the
    // spec, it is the delay used by both Firefox and Webkit, and thus matches
    // user expectations.
    static const int kRequestTimerDelay = 3000;

    // The cached remote typeface reference both provides load event callbacks
    // to the remote typeface cache for this remote typeface, and also ensures
    // that the remote typeface is retained in the remote typeface cache's
    // memory for as long as this reference exists.
    std::unique_ptr<loader::font::CachedRemoteTypefaceReferenceWithCallbacks>
        cached_remote_typeface_reference_;

    // The request timer is started on object creation and triggers a load event
    // callback when the timer expires. Before the timer expires, font lists
    // that use this font will be rendered transparently to avoid a flash of
    // text from briefly displaying a fallback font. However, permanently hiding
    // the text while waiting for it to load is considered non-conformant
    // behavior by the spec, so after the timer expires, the fallback font
    // becomes visible (https://www.w3.org/TR/css3-fonts/#font-face-loading).
    std::unique_ptr<base::OneShotTimer> request_timer_;
  };

  struct FontListInfo {
    scoped_refptr<FontList> font_list;
    base::TimeTicks inactive_time;
  };

  struct FontKey {
    FontKey(render_tree::TypefaceId key_typeface_id, float key_size)
        : typeface_id(key_typeface_id), size(key_size) {}

    bool operator<(const FontKey& rhs) const {
      if (typeface_id != rhs.typeface_id) {
        return typeface_id < rhs.typeface_id;
      } else {
        return size < rhs.size;
      }
    }

    render_tree::TypefaceId typeface_id;
    float size;
  };

  struct FontInfo {
    scoped_refptr<render_tree::Font> font;
    base::TimeTicks inactive_time;
  };

  struct InactiveFontKey {
    InactiveFontKey(base::TimeTicks time, FontKey key)
        : inactive_time(time), font_key(key) {}

    bool operator<(const InactiveFontKey& rhs) const {
      if (inactive_time != rhs.inactive_time) {
        return inactive_time < rhs.inactive_time;
      } else {
        return font_key < rhs.font_key;
      }
    }

    base::TimeTicks inactive_time;
    FontKey font_key;
  };

  struct CharacterFallbackKey {
    explicit CharacterFallbackKey(const render_tree::FontStyle& key_style)
        : style(key_style) {}

    bool operator<(const CharacterFallbackKey& rhs) const {
      if (style.weight != rhs.style.weight) {
        return style.weight < rhs.style.weight;
      } else {
        return style.slant < rhs.style.slant;
      }
    }

    render_tree::FontStyle style;
  };

  // Font-face related
  typedef std::map<std::string, FontFaceStyleSet> FontFaceMap;
  typedef std::map<GURL, scoped_refptr<RequestedRemoteTypefaceInfo> >
      RequestedRemoteTypefaceMap;

  // Font list related
  typedef std::map<FontListKey, FontListInfo> FontListMap;

  // Typeface/Font related
  typedef base::small_map<
      std::map<render_tree::TypefaceId, scoped_refptr<render_tree::Typeface> >,
      7>
      TypefaceMap;
  typedef std::map<FontKey, FontInfo> FontMap;
  typedef std::set<InactiveFontKey> InactiveFontSet;

  // Character fallback related
  typedef base::hash_map<int32, scoped_refptr<render_tree::Typeface> >
      CharacterFallbackTypefaceMap;
  typedef std::map<CharacterFallbackKey, CharacterFallbackTypefaceMap>
      CharacterFallbackTypefaceMaps;

  FontCache(render_tree::ResourceProvider** resource_provider,
            loader::font::RemoteTypefaceCache* remote_typeface_cache,
            const base::Closure& external_typeface_load_event_callback,
            const std::string& language_script,
            scoped_refptr<Location> document_location);

  // Set a new font face map. If it matches the old font face map then nothing
  // is done. Otherwise, it is updated with the new value and the remote
  // typeface containers are purged of URLs that are no longer contained within
  // the map.
  void SetFontFaceMap(std::unique_ptr<FontFaceMap> font_face_map);

  // Purge all caches within the font cache.
  void PurgeCachedResources();

  // Process unused font lists and fonts, potentially purging them from the
  // cache if they meet the removal requirements.
  void ProcessInactiveFontListsAndFonts();

  // Looks up and returns the font list in |font_list_map_|. If the font list
  // doesn't already exist, then a new one is created and added to the cache.
  const scoped_refptr<FontList>& GetFontList(const FontListKey& font_list_key);

  // Looks up and returns the font with the matching typeface and size in
  // |font_map_|. If it doesn't already exist in the cache, then a new font is
  // created from typeface and added to the cache.
  const scoped_refptr<render_tree::Font>& GetFontFromTypefaceAndSize(
      const scoped_refptr<render_tree::Typeface>& typeface, float size);

  // Attempts to retrieve a font. If the family maps to a font face, then this
  // makes a request to |TryGetRemoteFont()|; otherwise, it makes a request
  // to |TryGetLocalFont()|. This function may return NULL.
  scoped_refptr<render_tree::Font> TryGetFont(const std::string& family,
                                              render_tree::FontStyle style,
                                              float size,
                                              FontListFont::State* state);

  // Returns the character fallback typeface map associated with the specified
  // style. Each unique style has its own exclusive map. If it doesn't already
  // exist in the cache, then it is created during the request.
  // NOTE: This map is provided by the font cache so that all font lists with
  // the same style can share the same map. However, the cache itself does not
  // populate or query the map.
  CharacterFallbackTypefaceMap& GetCharacterFallbackTypefaceMap(
      const render_tree::FontStyle& style);

  // Retrieves the typeface associated with a UTF-32 character and style from
  // the resource provider.
  // NOTE: |character_fallback_typeface_maps_| is not queried before retrieving
  // the typeface from the resource provider. It is expected that the font list
  // will query its specific map first.
  const scoped_refptr<render_tree::Typeface>& GetCharacterFallbackTypeface(
      int32 utf32_character, const render_tree::FontStyle& style);

  // Given a string of text, returns the glyph buffer needed to render it.
  scoped_refptr<render_tree::GlyphBuffer> CreateGlyphBuffer(
      const base::char16* text_buffer, int32 text_length, bool is_rtl,
      FontList* font_list);

  // Given a string of text, return its width. This is faster than
  // CreateGlyphBuffer().
  float GetTextWidth(const base::char16* text_buffer, int32 text_length,
                     bool is_rtl, FontList* font_list,
                     render_tree::FontVector* maybe_used_fonts);

 private:
  render_tree::ResourceProvider* resource_provider() const {
    return *resource_provider_;
  }

  void ProcessInactiveFontLists(const base::TimeTicks& current_time);
  void ProcessInactiveFonts(const base::TimeTicks& current_time);

  // Looks up and returns the cached typeface in |local_typeface_map_|. If it
  // doesn't already exist in the cache, then the passed in typeface is added to
  // the cache.
  const scoped_refptr<render_tree::Typeface>& GetCachedLocalTypeface(
      const scoped_refptr<render_tree::Typeface>& typeface);

  // Returns the font if it is in the remote typeface cache and available;
  // otherwise returns NULL.
  // If the font is in the cache, but is not loaded, this call triggers an
  // asynchronous load of it. Both an external load even callback, provided by
  // the constructor and an |OnRemoteFontLoadEvent| callback provided by the
  // font are registered with the remote typeface cache to be called when the
  // load finishes.
  scoped_refptr<render_tree::Font> TryGetRemoteFont(const GURL& url, float size,
                                                    FontListFont::State* state);

  // Returns NULL if the requested family is not empty and is not available in
  // the resource provider. Otherwise, returns the best matching local font.
  scoped_refptr<render_tree::Font> TryGetLocalFont(const std::string& family,
                                                   render_tree::FontStyle style,
                                                   float size,
                                                   FontListFont::State* state);

  // Lookup by a typeface (aka font_face), typeface is defined as font family +
  // style (weight, width, and style).
  // Returns NULL if the requested font face is not found.
  scoped_refptr<render_tree::Font> TryGetLocalFontByFaceName(
      const std::string& font_face, float size, FontListFont::State* state);

  // Called when a remote typeface either successfully loads or fails to load.
  // In either case, the event can impact the fonts contained within the font
  // lists. As a result, the font lists need to have their loading fonts reset
  // so that they'll be re-requested from the cache.
  void OnRemoteTypefaceLoadEvent(const GURL& url);

  render_tree::ResourceProvider** resource_provider_;

  // TODO: Explore eliminating the remote typeface cache and moving its
  // logic into the font cache when the loader interface improves.
  loader::font::RemoteTypefaceCache* const remote_typeface_cache_;
  const base::Closure external_typeface_load_event_callback_;
  const std::string language_script_;

  // Font-face related
  // The cache contains a map of font faces and handles requesting typefaces by
  // url on demand from |remote_typeface_cache_| with a load event callback
  // provided by the constructor. Cached remote typeface returned by
  // |remote_typeface_cache_| have a reference retained by the cache for as long
  // as the cache contains a font face with the corresponding url, to ensure
  // that they remain in memory.
  std::unique_ptr<FontFaceMap> font_face_map_;
  RequestedRemoteTypefaceMap requested_remote_typeface_cache_;

  // Font list related
  // This maps unique font property combinations that are currently in use
  // within the document to the font lists that provides the functionality
  // associated with those font property combinations.
  FontListMap font_list_map_;

  // Typeface/Font related
  // Maps of the local typefaces and fonts currently cached. These are used so
  // that the same typefaces and fonts can be shared across multiple font lists,
  // thereby also sharing the internal caching within typeface and font objects.
  // NOTE: Remote typefaces are not cached in |local_typeface_map_|, as the
  // RemoteTypefaceCache handles caching of them.
  TypefaceMap local_typeface_map_;
  FontMap font_map_;
  InactiveFontSet inactive_font_set_;

  // Fallback font related
  // Contains maps of both the unique typeface to use with a specific
  // character-style combination and a prototype font for the typeface, which
  // can be used to provide copies of the font at any desired size, without
  // requiring an additional request of the resource provider for each newly
  // encountered size.
  CharacterFallbackTypefaceMaps character_fallback_typeface_maps_;

  // The last time the cache was checked for inactivity.
  base::TimeTicks last_inactive_process_time_;

  // Thread checker used to verify safe thread usage of the font cache.
  THREAD_CHECKER(thread_checker_);

  // Font cache's corresponding document's location object. It can provide
  // document's origin.
  scoped_refptr<Location> document_location_;
};

}  // namespace dom
}  // namespace cobalt

#endif  // COBALT_DOM_FONT_CACHE_H_
