// 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_BROWSER_WEB_MODULE_H_
#define COBALT_BROWSER_WEB_MODULE_H_

#include <memory>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "cobalt/base/address_sanitizer.h"
#include "cobalt/base/source_location.h"
#include "cobalt/browser/lifecycle_observer.h"
#include "cobalt/browser/screen_shot_writer.h"
#include "cobalt/browser/splash_screen_cache.h"
#include "cobalt/css_parser/parser.h"
#include "cobalt/cssom/viewport_size.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/input_event_init.h"
#include "cobalt/dom/keyboard_event_init.h"
#include "cobalt/dom/local_storage_database.h"
#include "cobalt/dom/media_source.h"
#include "cobalt/dom/on_screen_keyboard_bridge.h"
#include "cobalt/dom/pointer_event_init.h"
#include "cobalt/dom/screenshot_manager.h"
#include "cobalt/dom/wheel_event_init.h"
#include "cobalt/dom/window.h"
#include "cobalt/dom_parser/parser.h"
#include "cobalt/layout/layout_manager.h"
#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/math/size.h"
#include "cobalt/media/can_play_type_handler.h"
#include "cobalt/media/media_module.h"
#include "cobalt/render_tree/node.h"
#include "cobalt/render_tree/resource_provider.h"
#include "cobalt/ui_navigation/nav_item.h"
#include "cobalt/ui_navigation/scroll_engine/scroll_engine.h"
#include "cobalt/web/agent.h"
#include "cobalt/web/blob.h"
#include "cobalt/web/context.h"
#include "cobalt/web/csp_delegate.h"
#include "cobalt/web/environment_settings.h"
#include "cobalt/web/user_agent_platform_info.h"
#include "cobalt/webdriver/session_driver.h"
#include "starboard/atomic.h"
#include "url/gurl.h"

#if defined(ENABLE_DEBUGGER)
#include "cobalt/debug/backend/debug_dispatcher.h"  // nogncheck
#include "cobalt/debug/backend/debugger_state.h"    // nogncheck
#include "cobalt/debug/backend/render_overlay.h"    // nogncheck
#include "cobalt/debug/console/command_manager.h"   // nogncheck
#endif                                              // ENABLE_DEBUGGER

namespace cobalt {
namespace browser {

// WebModule hosts all components of Cobalt that deal with or implement the
// WebAPI.  This includes the ability to fetch resources given a URL, parse
// various web formats like HTML and CSS, host a DOM tree, manage a JavaScript
// engine, and lay out a web page.  Ultimately, interaction with WebModule is
// done through calls to InjectEvent() such as when dealing with external input
// (e.g. keyboards and gamepads), and handling render tree output from WebModule
// when it calls the on_render_tree_produced_ callback (provided upon
// construction).
// At creation, the WebModule starts a dedicated thread, on which a private
// implementation object is constructed that manages all internal components.
// All methods of the WebModule post tasks to the implementation object on that
// thread, so all internal functions are executed synchronously with respect to
// each other.
// This necessarily implies that details contained within WebModule, such as the
// DOM, are intentionally kept private, since these structures expect to be
// accessed from only one thread.
class WebModule : public base::MessageLoop::DestructionObserver,
                  public LifecycleObserver {
 public:
  struct Options {
    typedef base::Callback<scoped_refptr<script::Wrappable>(
        WebModule*, web::EnvironmentSettings*)>
        CreateObjectFunction;
    typedef base::hash_map<std::string, CreateObjectFunction>
        InjectedGlobalObjectAttributes;

    // All optional parameters defined in this structure should have their
    // values initialized in the default constructor to useful defaults.
    Options();

    web::Agent::Options web_options;

    // The LayoutTrigger parameter dictates when a layout should be triggered.
    // Tests will often set this up so that layouts are only performed when
    // we specifically request them to be.
    layout::LayoutManager::LayoutTrigger layout_trigger;

    // The navigation_callback functor will be called when JavaScript internal
    // to the WebModule requests a page navigation, e.g. by modifying
    // 'window.location.href'.
    base::Callback<void(const GURL&)> navigation_callback;

    // A list of callbacks to be called once the web page finishes loading.
    std::vector<base::Closure> loaded_callbacks;

    // Options to customize DOMSettings.
    dom::DOMSettings::Options dom_settings_options;

    // Whether Cobalt is forbidden to render without receiving CSP headers.
    csp::CSPHeaderPolicy csp_header_policy;

    // If true, Cobalt will log a warning each time it parses a non-async
    // <script> tag inlined in HTML.  Cobalt has a known issue where if it is
    // blurred or frozen while loading inlined <script> tags, it will abort
    // the script fetch and silently fail without any follow up actions.  It is
    // recommended that production code always avoid non-async <script> tags
    // inlined in HTML.  This is likely not an issue for tests, however, where
    // we control the freeze/unfreeze activities, so this flag can be used in
    // these cases to disable the warning.
    bool enable_inline_script_warnings = true;

    // Encoded image cache capacity in bytes.
    int encoded_image_cache_capacity = 1024 * 1024;

    // Image cache capacity in bytes.
    int image_cache_capacity = 32 * 1024 * 1024;

    // Typeface cache capacity in bytes.
    int remote_typeface_cache_capacity = 4 * 1024 * 1024;

    // Mesh cache capacity in bytes.
    int mesh_cache_capacity = 0;

    // Whether map-to-mesh is enabled.
    bool enable_map_to_mesh = true;

    // Content Security Policy enforcement mode for this web module.
    web::CspEnforcementType csp_enforcement_type = web::kCspEnforcementEnable;

    // Token obtained from CSP to allow creation of insecure delegates.
    int csp_insecure_allowed_token = 0;

    // Whether or not the web module's stat tracker should track event stats.
    bool track_event_stats = false;

    // If set to something other than 1.0f, when a video starts to play, the
    // image cache will be flushed and temporarily multiplied by this value (
    // must be less than or equal to 1.0f) until the video ends.  This can
    // help for platforms that are low on image memory while playing a video.
    float image_cache_capacity_multiplier_when_playing_video = 1.0f;

    // Specifies the priority that the web module's corresponding loader thread
    // will be assigned.  This is the thread responsible for performing resource
    // decoding, such as image decoding.  The default value is
    // base::ThreadPriority::BACKGROUND.
    base::ThreadPriority loader_thread_priority =
        base::ThreadPriority::BACKGROUND;

    // Specifies the priority that the web module's animated image decoding
    // thread will be assigned. This thread is responsible for decoding,
    // blending and constructing individual frames from animated images. The
    // default value is base::ThreadPriority::BACKGROUND.
    base::ThreadPriority animated_image_decode_thread_priority =
        base::ThreadPriority::BACKGROUND;

    // To support 3D camera movements.
    scoped_refptr<input::Camera3D> camera_3d;

    // The video playback rate will be multiplied with the following value.  Its
    // default value is 1.0.
    float video_playback_rate_multiplier = 1.f;

    // Allows image animations to be enabled/disabled.  Its default value
    // is true to enable them.
    bool enable_image_animations = true;

    // Whether or not to retain the remote typeface cache when the app enters
    // the frozen state.
    bool should_retain_remote_typeface_cache_on_freeze = false;

    // The splash screen cache object, owned by the BrowserModule.
    SplashScreenCache* splash_screen_cache = nullptr;

    // The beforeunload event can give a web page a chance to shut
    // itself down softly and ultimately call window.close(), however
    // if it is not handled by the web application, we indicate this
    // situation externally by calling this callback, so that if the
    // beforeunload event was generated it can be known that there is
    // no window.close() call pending.
    base::Closure on_before_unload_fired_but_not_handled;

    // The dom::OnScreenKeyboard forwards calls to this interface.
    dom::OnScreenKeyboardBridge* on_screen_keyboard_bridge = nullptr;

    // This function takes in a render tree as input, and then calls the 2nd
    // argument (which is another callback) when the screenshot is available.
    // The callback's first parameter points to an unencoded image, where the
    // format is R8G8B8A8 pixels (with no padding at the end of each row),
    // and the second parameter is the dimensions of the image.
    // Note that the callback could be called on a different thread, and is not
    // guaranteed to be called on the caller thread.
    // By using Callbacks here, it is easier to write tests, and use this
    // functionality in Cobalt.
    dom::ScreenshotManager::ProvideScreenshotFunctionCallback
        provide_screenshot_function;

    // If true, the initial containing block's background color will be applied
    // as a clear, i.e. with blending disabled.  This means that a background
    // color of transparent will replace existing pixel values, effectively
    // clearing the screen.
    bool clear_window_with_background_color = true;

    // As a preventative measure against Spectre attacks, we explicitly limit
    // the resolution of the performance timer by default.  Setting this option
    // can allow the limit to be disabled.
    bool limit_performance_timer_resolution = true;

#if defined(ENABLE_DEBUGGER)
    // Whether the debugger should block until remote devtools connects.
    bool wait_for_web_debugger = false;

    // The debugger state returned from a previous web module's FreezeDebugger()
    // that should be restored in the new WebModule after navigation. Null if
    // there is no state to restore.
    debug::backend::DebuggerState* debugger_state = nullptr;
#endif  // defined(ENABLE_DEBUGGER)

    // This callback is for checking the mediasession actions transitions. When
    // there is no playback during Concealed state, we should provide a chance
    // for Cobalt to freeze.
    base::Closure maybe_freeze_callback;

    // This callback is for collecting previous document unload event start/end
    // time.
    base::Callback<void(base::TimeTicks, base::TimeTicks)>
        collect_unload_event_time_callback;

    // injected_global_attributes contains a map of attributes to be injected
    // into the Web Agent's window object upon construction.  This provides
    // a mechanism to inject custom APIs into the Web Agent object.
    InjectedGlobalObjectAttributes injected_global_object_attributes;
  };

  typedef layout::LayoutManager::LayoutResults LayoutResults;
  typedef base::Callback<void(const LayoutResults&)>
      OnRenderTreeProducedCallback;
  typedef base::Callback<void(const GURL&, const std::string&)> OnErrorCallback;
  typedef dom::Window::CloseCallback CloseCallback;

  explicit WebModule(const std::string& name);
  ~WebModule();
  void Run(const GURL& initial_url,
           base::ApplicationState initial_application_state,
           ui_navigation::scroll_engine::ScrollEngine* scroll_engine,
           const OnRenderTreeProducedCallback& render_tree_produced_callback,
           OnErrorCallback error_callback,
           const CloseCallback& window_close_callback,
           const base::Closure& window_minimize_callback,
           media::CanPlayTypeHandler* can_play_type_handler,
           media::MediaModule* media_module,
           const cssom::ViewportSize& window_dimensions,
           render_tree::ResourceProvider* resource_provider,
           float layout_refresh_rate, const Options& options);

  // Injects an on screen keyboard input event into the web module. The value
  // for type represents beforeinput or input.
  void InjectOnScreenKeyboardInputEvent(base::Token type,
                                        const dom::InputEventInit& event);
  // Injects an on screen keyboard shown event into the web module.
  void InjectOnScreenKeyboardShownEvent(int ticket);
  // Injects an on screen keyboard hidden event into the web module.
  void InjectOnScreenKeyboardHiddenEvent(int ticket);
  // Injects an on screen keyboard focused event into the web module.
  void InjectOnScreenKeyboardFocusedEvent(int ticket);
  // Injects an on screen keyboard blurred event into the web module.
  void InjectOnScreenKeyboardBlurredEvent(int ticket);
  // Injects an on screen keyboard suggestions updated event into the web
  // module.
  void InjectOnScreenKeyboardSuggestionsUpdatedEvent(int ticket);

  void InjectWindowOnOnlineEvent(const base::Event* event);
  void InjectWindowOnOfflineEvent(const base::Event* event);

  // Injects a keyboard event into the web module. The value for type
  // represents the event name, for example 'keydown' or 'keyup'.
  void InjectKeyboardEvent(base::Token type,
                           const dom::KeyboardEventInit& event);

  // Injects a pointer event into the web module. The value for type represents
  // the event name, for example 'pointerdown', 'pointerup', or 'pointermove'.
  void InjectPointerEvent(base::Token type, const dom::PointerEventInit& event);

  // Injects a wheel event into the web module. The value for type represents
  // the event name, for example 'wheel'.
  void InjectWheelEvent(base::Token type, const dom::WheelEventInit& event);

  // Injects a beforeunload event into the web module. If this event is not
  // handled by the web application, |on_before_unload_fired_but_not_handled_|
  // will be called.
  void InjectBeforeUnloadEvent();

  void InjectCaptionSettingsChangedEvent();

  // Update the date/time configuration of relevant web modules.
  void UpdateDateTimeConfiguration();

  // Executes Javascript code in this web module.  The calling thread will
  // block until the JavaScript has executed and the output results are
  // available.
  void ExecuteJavascript(const std::string& script_utf8,
                         const base::SourceLocation& script_location,
                         std::string* out_result = nullptr,
                         bool* out_succeeded = nullptr);

#if defined(ENABLE_WEBDRIVER)
  // Creates a new webdriver::WindowDriver that interacts with the Window that
  // is owned by this WebModule instance.
  void CreateWindowDriver(
      const webdriver::protocol::WindowId& window_id,
      std::unique_ptr<webdriver::WindowDriver>* window_driver_out);
#endif

#if defined(ENABLE_DEBUGGER)
  // Gets a reference to the debug dispatcher that interacts with this web
  // module. The debug dispatcher is part of the debug module owned by this web
  // module, which is lazily created by this function if necessary.
  void GetDebugDispatcher(debug::backend::DebugDispatcher** dispatcher);

  // Moves the debugger state out of this WebModule prior to navigating so that
  // it can be restored in the new WebModule after the navigation.
  void FreezeDebugger(
      std::unique_ptr<debug::backend::DebuggerState>* debugger_state);
#endif  // ENABLE_DEBUGGER

  // Sets the size of this web module, possibly causing relayout and re-render
  // with the new parameters. Does nothing if the parameters are not different
  // from the current parameters.
  void SetSize(const cssom::ViewportSize& viewport_size);

  void UpdateCamera3D(const scoped_refptr<input::Camera3D>& camera_3d);
  void SetMediaModule(media::MediaModule* media_module);
  void SetImageCacheCapacity(int64_t bytes);
  void SetRemoteTypefaceCacheCapacity(int64_t bytes);

  // This returns the UI navigation root container which contains all active
  // UI navigation items created by this web module.
  const scoped_refptr<ui_navigation::NavItem>& GetUiNavRoot() const {
    return ui_nav_root_;
  }

  // LifecycleObserver implementation
  void Blur(SbTimeMonotonic timestamp) override;
  void Conceal(render_tree::ResourceProvider* resource_provider,
               SbTimeMonotonic timestamp) override;
  void Freeze(SbTimeMonotonic timestamp) override;
  void Unfreeze(render_tree::ResourceProvider* resource_provider,
                SbTimeMonotonic timestamp) override;
  void Reveal(render_tree::ResourceProvider* resource_provider,
              SbTimeMonotonic timestamp) override;
  void Focus(SbTimeMonotonic timestamp) override;

  // Attempt to reduce overall memory consumption. Called in response to a
  // system indication that memory usage is nearing a critical level.
  void ReduceMemory();

  // Post a task that gets the current |script::HeapStatistics| for our
  // |JavaScriptEngine| to the web module thread, and then passes that to
  // |callback|.  Note that |callback| will be called on the main web module
  // thread.  It is the responsibility of |callback| to get back to its
  // intended thread should it want to.
  void RequestJavaScriptHeapStatistics(
      const web::Agent::JavaScriptHeapStatisticsCallback& callback);

  // Indicate the web module is ready to freeze.
  bool IsReadyToFreeze();

  void DoSynchronousLayoutAndGetRenderTree(
      scoped_refptr<render_tree::Node>* render_tree = nullptr);

  // Pass the application preload or start timestamps from Starboard.
  void SetApplicationStartOrPreloadTimestamp(bool is_preload,
                                             SbTimeMonotonic timestamp);
  void SetDeepLinkTimestamp(SbTimeMonotonic timestamp);

  // From base::MessageLoop::DestructionObserver.
  void WillDestroyCurrentMessageLoop() override;

  // Set document's load timing info's unload event start/end time.
  void SetUnloadEventTimingInfo(base::TimeTicks start_time,
                                base::TimeTicks end_time);

 private:
  // Data required to construct a WebModule, initialized in the constructor and
  // passed to |InitializeTaskInThread|.
  struct ConstructionData {
    ConstructionData(const GURL& initial_url,
                     base::ApplicationState initial_application_state,
                     ui_navigation::scroll_engine::ScrollEngine* scroll_engine,
                     OnRenderTreeProducedCallback render_tree_produced_callback,
                     const OnErrorCallback& error_callback,
                     CloseCallback window_close_callback,
                     base::Closure window_minimize_callback,
                     media::CanPlayTypeHandler* can_play_type_handler,
                     media::MediaModule* media_module,
                     const cssom::ViewportSize& window_dimensions,
                     render_tree::ResourceProvider* resource_provider,
                     int dom_max_element_depth, float layout_refresh_rate,
                     const scoped_refptr<ui_navigation::NavItem>& ui_nav_root,
#if defined(ENABLE_DEBUGGER)
                     starboard::atomic_bool* waiting_for_web_debugger,
#endif  // defined(ENABLE_DEBUGGER)
                     base::WaitableEvent* synchronous_loader_interrupt,
                     const Options& options)
        : initial_url(initial_url),
          initial_application_state(initial_application_state),
          scroll_engine(scroll_engine),
          render_tree_produced_callback(render_tree_produced_callback),
          error_callback(error_callback),
          window_close_callback(window_close_callback),
          window_minimize_callback(window_minimize_callback),
          can_play_type_handler(can_play_type_handler),
          media_module(media_module),
          window_dimensions(window_dimensions),
          resource_provider(resource_provider),
          dom_max_element_depth(dom_max_element_depth),
          layout_refresh_rate(layout_refresh_rate),
          ui_nav_root(ui_nav_root),
#if defined(ENABLE_DEBUGGER)
          waiting_for_web_debugger(waiting_for_web_debugger),
#endif  // defined(ENABLE_DEBUGGER)
          synchronous_loader_interrupt(synchronous_loader_interrupt),
          options(options) {
    }

    GURL initial_url;
    base::ApplicationState initial_application_state;
    ui_navigation::scroll_engine::ScrollEngine* scroll_engine;
    OnRenderTreeProducedCallback render_tree_produced_callback;
    OnErrorCallback error_callback;
    CloseCallback window_close_callback;
    base::Closure window_minimize_callback;
    media::CanPlayTypeHandler* can_play_type_handler;
    media::MediaModule* media_module;
    cssom::ViewportSize window_dimensions;
    render_tree::ResourceProvider* resource_provider;
    int dom_max_element_depth;
    float layout_refresh_rate;
    scoped_refptr<ui_navigation::NavItem> ui_nav_root;
#if defined(ENABLE_DEBUGGER)
    starboard::atomic_bool* waiting_for_web_debugger;
#endif  // defined(ENABLE_DEBUGGER)
    base::WaitableEvent* synchronous_loader_interrupt;
    Options options;
  };

  // Forward declaration of the private implementation class.
  class Impl;

  // Called by |Run| to create the private implementation object and
  // perform any other initialization required on the dedicated thread.
  void InitializeTaskInThread(const ConstructionData& data,
                              web::Context* context);

  void ClearAllIntervalsAndTimeouts();

  void GetIsReadyToFreeze(volatile bool* is_ready_to_freeze);

  // The message loop this object is running on.
  base::MessageLoop* message_loop() const {
    DCHECK(web_agent_);
    return web_agent_ ? web_agent_->message_loop() : nullptr;
  }

  // Private implementation object.
  std::unique_ptr<Impl> impl_;

  web::Agent* web_agent() const { return web_agent_.get(); }

  // The Web Agent.
  std::unique_ptr<web::Agent> web_agent_;

  // This is the root UI navigation container which contains all active UI
  // navigation items created by this web module.
  scoped_refptr<ui_navigation::NavItem> ui_nav_root_;

#if defined(ENABLE_DEBUGGER)
  // Used to avoid a deadlock when running |Blur| while waiting for the web
  // debugger to connect. Initializes to false.
  starboard::atomic_bool waiting_for_web_debugger_;
#endif  // defined(ENABLE_DEBUGGER)

  // This event is used to interrupt the loader when JavaScript is loaded
  // synchronously.  It is manually reset so that events like Freeze can be
  // correctly execute, even if there are multiple synchronous loads in queue
  // before the freeze (or other) event handlers.
  base::WaitableEvent synchronous_loader_interrupt_ = {
      base::WaitableEvent::ResetPolicy::MANUAL,
      base::WaitableEvent::InitialState::NOT_SIGNALED};
};

}  // namespace browser
}  // namespace cobalt

#endif  // COBALT_BROWSER_WEB_MODULE_H_
