// 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 "base/threading/thread_checker.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/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 require_csp;

    // 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_mode = 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,
           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);
  bool SetMediaSourceSetting(const std::string& name, int value);
  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,
                     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),
          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;
    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);

  void SetMediaSourceSettingInternal(const std::string& name, int value,
                                     bool* succeeded);

  // 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_
