// 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/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 {
    // All optional parameters defined in this structure should have their
    // values initialized in the default constructor to useful defaults.
    explicit Options(const std::string& name);

    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;
  };

  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;

  WebModule(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);
  ~WebModule();

  // 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 |Initialize|.
  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 the constructor to create the private implementation object and
  // perform any other initialization required on the dedicated thread.
  void Initialize(const ConstructionData& data, web::Context* context);

  void ClearAllIntervalsAndTimeouts();

  void CancelSynchronousLoads();

  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_->message_loop();
  }

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