// Copyright 2015 Google Inc. 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 <set>
#include <string>
#include <utility>

#include "base/callback.h"
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/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 "googleurl/src/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.
    scoped_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).
    scoped_ptr<base::Timer> 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::SmallMap<
      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,
            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(scoped_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 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 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_;

  // 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.
  scoped_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.
  base::ThreadChecker 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_
