// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.web;

using fuchsia.logger;
using fuchsia.media.sessions2;
using fuchsia.mem;
using fuchsia.settings;
using fuchsia.ui.gfx;
using fuchsia.ui.views;

// TODO(fxbug.dev/29927): Consider using [`fuchsia.logger/LogLevelFilter`] if possible.
type ConsoleLogLevel = strict enum : int32 {
    /// No logging.
    NONE = 100;

    /// Outputs messages from `console.debug()` and above levels.
    DEBUG = -1;

    /// Outputs messages from `console.log()`, `console.info()` and above levels.
    INFO = 0;

    /// Outputs messages from `console.warn()` and `console.error()`.
    WARN = 1;

    /// Outputs messages from `console.error()`.
    ERROR = 2;
};

/// Identifies the types of input events which may be handled by a View.
type InputTypes = strict bits : uint64 {
    /// Keyboard events.
    KEY = 0x1;

    /// Mouse button events, for any button.
    MOUSE_CLICK = 0x2;

    /// Mouse scroll wheel events.
    MOUSE_WHEEL = 0x4;

    /// Mouse movement events.
    MOUSE_MOVE = 0x8;

    /// Single tapping with one finger.
    GESTURE_TAP = 0x10;

    /// Pinching (for zooming).
    GESTURE_PINCH = 0x20;

    /// Dragging a finger (for scrolling).
    GESTURE_DRAG = 0x40;

    /// Matches all input types.
    ALL = 0x8000000000000000;
};

/// Controls whether [`Frame.ConfigureInputTypes()`] should allow or deny processing of the
/// specified [`InputTypes`].
type AllowInputState = strict enum : int32 {
    ALLOW = 1;
    DENY = 2;
};

/// Represents the return status of a [`Frame`] method.
type FrameError = strict enum : int32 {
    /// An internal error occured.
    INTERNAL_ERROR = 1;

    /// The provided buffer is not UTF-8 encoded.
    BUFFER_NOT_UTF8 = 2;

    /// The Frame's URL does not match any of the origins provided by the caller.
    INVALID_ORIGIN = 3;

    /// The required `data` property is missing from a [`WebMessage`].
    NO_DATA_IN_MESSAGE = 4;
};

/// Identifies a type of permission that may be granted to a web origin.
type PermissionType = strict enum : uint16 {
    /// Permission to access microphone(s).
    MICROPHONE = 1;

    /// Permission to access camera(s).
    CAMERA = 2;

    /// Permission to use device identifier(s) for EME.
    PROTECTED_MEDIA_IDENTIFIER = 3;

    /// Permission to use persistent storage.
    PERSISTENT_STORAGE = 4;
};

/// Describes a web permission. In the future, it may be extended with type-specific fields.
type PermissionDescriptor = table {
    1: type PermissionType;
};

/// A state for a web permission.
type PermissionState = strict enum : uint8 {
    /// Permission is denied.
    DENIED = 1;

    /// Permission is granted.
    GRANTED = 2;
};

/// Settings for the web content in the Frame. Popup Frames created by the Frame will have their
/// settings initialized to the Frame's current settings.
type ContentAreaSettings = table {
    /// Specifies whether scrollbars are hidden for the Frame. If omitted, the default is false.
    1: hide_scrollbars bool;

    /// Specifies the autoplay policy for the Frame. If omitted, the default policy is
    /// `REQUIRE_USER_ACTIVATION`.
    2: autoplay_policy AutoplayPolicy;

    /// Specifies the color theme reported to web content via the `prefers-color-scheme` media
    /// query.
    /// Valid inputs are `LIGHT`, `DARK`, and `DEFAULT`. If omitted, the default is LIGHT theme.
    /// Specifying `DEFAULT` means using the system settings, and requires that the [`Context`] have
    /// the [`fuchsia.settings.Display`] service. If the service is not available, the [`Frame`]
    /// will disconnect with `ZX_ERR_INVALID_ARGS`.
    3: theme fuchsia.settings.ThemeType;

    /// Sets scale factor (zoom level) that should be applied to web content rendered in this
    /// frame. Values above 1.0 make all web content (including text and images) larger, while
    /// values below 1.0 will make it smaller. In other words, values above 1.0 are used to zoom in
    /// and values below 1.0 zoom out. The overall ratio between physical pixel and CSS pixel is a
    /// product of the scale set with this method and the scale provided by Scenic (see
    /// [`fuchsia.ui.gfx.Metrics`]). That product is visible to the web content as
    /// `window.devicePixelRatio`. If omitted, the default is 1.0.
    ///
    /// This setting does not have any effect on the size of the view on the screen and the
    /// resolution at which the view is rendered. Native (non-web) UI elements, such as default
    /// scroll bars and default mouse cursor, are not scaled. User may zoom the page further when
    /// pinch-zoom is enabled (see [`InputTypes.GESTURE_PINCH`]).
    4: page_scale float32;
};

protocol Frame {
    /// Creates a new view using the specified `view_token`. Caller should pass the other end of
    /// the token to [`fuchsia.ui.gfx/ViewHolderArgs`] to attach the new view to a view tree.
    ///
    /// See the description of [`CreateContextParams.service_directory`] for additional services
    /// that must be present when using this method.
    CreateView(resource struct {
        view_token fuchsia.ui.views.ViewToken;
    });

    /// Creates a new view using the specified `view_token`. Caller should pass the other end of
    /// the token to [`fuchsia.ui.gfx/ViewHolderArgs`] to attach the new view to a view tree.
    /// `view_ref` can be cloned before passing it to this method, which will allow clients to
    /// track the view.
    ///
    /// `view_ref_control` must not have the `ZX_RIGHT_DUPLICATE` set, or view creation will fail
    /// and `view_token` will be closed.
    ///
    /// See the description of [`CreateContextParams.service_directory`] for additional services
    /// that must be present when using this method.
    CreateViewWithViewRef(resource struct {
        view_token fuchsia.ui.views.ViewToken;
        view_ref_control fuchsia.ui.views.ViewRefControl;
        view_ref fuchsia.ui.views.ViewRef;
    });

    /// Creates a new Flatland view using the specified `view_creation_token` defined under `args`.
    /// Caller should pass the other end of the token to
    /// [`fuchsia.ui.composition/Flatland.CreateViewport`] to attach the new Flatland view to its
    /// graph.
    // TODO(fxbug.dev/81959): use "resource table" syntax when it becomes available, thus getting
    // rid of the need for CreateView2Args.  Hopefully this will be done by the time we want to
    // rename CreateView2() to CreateView(), once the latter is deleted.
    @transitional
    CreateView2(resource struct {
        args CreateView2Args;
    });

    /// Enables headless rendering of the Frame.
    ///
    /// This is used when content depends on layout and/or animation events firing normally.
    /// May only be used on a Context created with the `HEADLESS` feature flag.
    EnableHeadlessRendering();

    /// Stops headless rendering of the Frame.
    ///
    /// May only be used on a Context created with the `HEADLESS` feature flag.
    DisableHeadlessRendering();

    /// Returns a [`fuchsia.media.sessions2/Player`] interface through which media (i.e.
    /// video/audio) playback in the frame may be observed, and/or controlled. Only one
    /// [`fuchsia.media.sessions2/Player`] may be active at a time, for each [`Frame`].
    GetMediaPlayer(resource struct {
        player server_end:fuchsia.media.sessions2.Player;
    });

    /// Returns an interface through which the [`Frame`] may be navigated to a desired URL,
    /// reloaded, etc.
    ///
    /// - `controller`: An asynchronous interface request for the [`Frame`]'s
    ///   [`NavigationController`].
    GetNavigationController(resource struct {
        controller server_end:NavigationController;
    });

    /// Executes a UTF-8 encoded `script` in the [`Frame`] if the [`Frame`]'s URL has an origin
    /// which matches entries in `origins`.
    ///
    /// At least one `origins` entry must be specified. If a wildcard `"*"` is specified in
    /// `origins`, then the script will be evaluated unconditionally.
    ///
    /// Returns the result of executing `script`, as a JSON-encoded string.
    ///
    /// Note that scripts share the same execution context as the document,
    /// meaning that document may modify variables, classes, or objects set by
    /// the script in arbitrary or unpredictable ways.
    ///
    /// If an error occured, the FrameError will be set to one of these values:
    /// - `BUFFER_NOT_UTF8`: `script` is not UTF-8 encoded.
    /// - `INVALID_ORIGIN`: The [`Frame`]'s current URL does not match any of the values in
    ///   `origins` or `origins` is an empty vector.
    ExecuteJavaScript(resource struct {
        origins vector<Url>:MAX;
        script fuchsia.mem.Buffer;
    }) -> (resource struct {
        result fuchsia.mem.Buffer;
    }) error FrameError;

    /// Variant of [`Frame.ExecuteJavaScript`] which executes the supplied script without returning
    /// a result.
    ExecuteJavaScriptNoResult(resource struct {
        origins vector<Url>:MAX;
        script fuchsia.mem.Buffer;
    }) -> (struct {}) error FrameError;

    /// Executes a UTF-8 encoded `script` for every subsequent page load where the [`Frame`]'s URL
    /// has an origin reflected in `origins`. The script is executed early, prior to the execution
    /// of the document's scripts.
    ///
    /// Scripts are identified by a client-managed identifier `id`. Any script previously injected
    /// using the same `id` will be replaced.
    ///
    /// The order in which multiple bindings are executed is the same as the order in which the
    /// bindings were added. If a script is added which clobbers an existing script of the same
    /// `id`, the previous script's precedence in the injection order will be preserved.
    ///
    /// At least one `origins` entry must be specified. If a wildcard `"*"` is specified in
    /// `origins`, then the script will be evaluated unconditionally.
    ///
    /// If an error occured, the [`FrameError`] will be set to one of these values:
    /// - `BUFFER_NOT_UTF8`: `script` is not UTF-8 encoded.
    /// - `INVALID_ORIGIN`: `origins` is an empty vector.
    AddBeforeLoadJavaScript(resource struct {
        id uint64;
        origins vector<Url>:MAX;
        script fuchsia.mem.Buffer;
    }) -> (struct {}) error FrameError;

    /// Removes a previously added JavaScript snippet identified by `id`. This is a no-op if there
    /// is no JavaScript snippet identified by `id`.
    RemoveBeforeLoadJavaScript(struct {
        id uint64;
    });

    /// Posts a message to the frame's onMessage handler.
    ///
    /// `target_origin` restricts message delivery to the specified origin. If `target_origin` is
    /// `"*"`, then the message will be sent to the document regardless of its origin.
    /// See the
    /// [HTML spec](https://html.spec.whatwg.org/multipage/web-messaging.html#posting-messages)
    /// section 9.4.3 for more details on how the target origin policy is applied.
    ///
    /// If an error occured, the [`FrameError`] will be set to one of these values:
    /// - `INTERNAL_ERROR`: The WebEngine failed to create a message pipe.
    /// - `BUFFER_NOT_UTF8`: The script in `message`'s `data` property is not UTF-8 encoded.
    /// - `INVALID_ORIGIN`: `origins` is an empty vector.
    /// - `NO_DATA_IN_MESSAGE`: The `data` property is missing in `message`.
    PostMessage(resource struct {
        target_origin Url;
        message WebMessage;
    }) -> (struct {}) error FrameError;

    /// Sets the listener for handling page navigation events.
    ///
    /// - `listener`: The observer to use. Unregisters any existing listener if null.
    @transitional
    SetNavigationEventListener(resource struct {
        listener client_end:<NavigationEventListener, optional>;
    });

    /// Sets the listener for handling page navigation events.
    ///
    /// - `listener`: The observer to use. Unregisters any existing listener if null.
    /// - `flags`: Flags for optional features that should be enabled for the listener.
    @transitional
    SetNavigationEventListener2(resource struct {
        listener client_end:<NavigationEventListener, optional>;
        flags NavigationEventListenerFlags;
    });

    /// If set to a value other than [`ConsoleLogLevel.NONE`], allows web content to log messages
    /// to the [`fuchsia.logger/LogSink`] configured for this [`Frame`], via the
    /// `console` object (e.g. using `debug()`, `log()`, `info()`, `warn()` and
    /// `error()`).
    /// The default value is [`ConsoleLogLevel.NONE`].
    ///
    /// As the system log may be persisted, it is recommended that [`ConsoleLogLevel.NONE`] be used
    /// in Incognito and other private browsing modes.
    ///
    /// Log lines are written to the [`fuchsia.logger/LogsSink`] configured
    /// for this [`fuchsia.web/Frame`], with severities mapped as follows:
    /// - `debug()`, `log()` and `info()` are logged at `INFO` severity.
    /// - `warn()` is logged at `WARN` severity.
    /// - `error()` is logged at `ERROR` severity.
    SetJavaScriptLogLevel(struct {
        level ConsoleLogLevel;
    });

    /// Specifies where to emit `console` log output to. By default log output will be routed to a
    /// [`fuchsia.logger/LogSink`] obtained via the [`fuchsia.web/Context`]'s service directory.
    ///
    /// - `sink`: The [`fuchsia.logger/LogSink`] to use to emit logs. Passing a `null` handle
    ///   resets logging to use the default [`fuchsia.logger/LogSink`].
    SetConsoleLogSink(resource struct {
        sink client_end:<fuchsia.logger.LogSink, optional>;
    });

    /// Enables or disables the processing of the specified `types` of user inputs.
    /// `allow` specifies whether to enable or disable the specified `types`.
    /// All input types are enabled by default.
    ConfigureInputTypes(struct {
        types InputTypes;
        allow AllowInputState;
    });

    /// Sets the listener for handling popup frame opened by web content. If no listener is
    /// present, then any new popup frame will be blocked.
    ///
    /// - `listener`: The listener to use. Unregisters any existing listener if null.
    SetPopupFrameCreationListener(resource struct {
        listener client_end:<PopupFrameCreationListener, optional>;
    });

    /// Supplies a set of [`UrlRequestRewriteRule`] to apply on every subsequent URL request.
    /// - `rules` are cumulative and applied in order.
    /// - `rules` will be validated before being applied. If `rules` are invalid, the [`Frame`]
    ///   will be closed with `ERR_INVALID_ARGS`.
    /// - [`Frame.SetUrlRequestRewriteRules`] must not be called again until its acknowledgement
    ///   callback has been processed. If this happens, the [`Frame`] will be closed with
    ///   `ERR_BAD_STATE`.
    SetUrlRequestRewriteRules(struct {
        rules vector<UrlRequestRewriteRule>:MAX_RULE_COUNT;
    }) -> ();

    /// Sets `session_id` to pass to the [`fuchsia.media/AudioConsumer`] when playing audio. The
    /// specified value is not applied retroactively to audio streams that were started before this
    /// message is processed. If the caller needs to ensure the value is applied to all streams it
    /// should call this method before [`Frame.GetNavigationController`].
    SetMediaSessionId(struct {
        session_id uint64;
    });

    /// Overrides the dimensions reported to web content. The devicePixelRatio reported to
    /// web content will be adjusted in response to changes in the pixel size of the View,
    /// rather than changing the size reported to the content. Call with null `web_dips` to
    /// remove any prior forced content dimensions.
    ForceContentDimensions(struct {
        web_dips box<fuchsia.ui.gfx.vec2>;
    });

    /// Sets the permission state for the specified `permission` and `web_origin`. By default, all
    /// permissions are denied.
    SetPermissionState(struct {
        permission PermissionDescriptor;
        web_origin Url;
        state PermissionState;
    });

    /// Sets whether to block all HTMLMediaElements in the frame from fetching and loading media
    /// resources.
    ///
    /// May be used, for example, to prevent loading media in frames that are not visible.
    ///
    /// While media loading is blocked, elements with `autoplay` set to `true` will not start
    /// playback. The promises returned by calls to `play()` will remain unresolved until loading is
    /// unblocked by a call to this method.
    ///
    /// When media loading is unblocked, elements will begin fetching, resource, loading, and
    /// playing as appropriate.
    ///
    /// Any elements that have begun fetching or loading media resources for the current source
    /// before media loading was blocked will continue to fetch, load, and start playback as
    /// appropriate. This includes calls to `play()` even after media loading is blocked.
    SetBlockMediaLoading(struct {
        blocked bool;
    });

    /// Returns the amount of private (non-shared) physical memory used by the Frame's main
    /// document. The returned size might not reflect the memory usage of embedded iframes.
    GetPrivateMemorySize() -> (struct {
        size_bytes uint64;
    });

    /// Sets the navigation policy provider for the [`Frame`]. When set, the [`Frame`] sends
    /// [`NavigationPolicyProvider.EvaluateRequestedNavigation`] when processing navigation
    /// requests. `params` defines when the message is sent. After sending the
    /// `EvaluateRequestedNavigation` message, the [`Frame`] blocks the corresponding navigation
    /// until it receives a response.
    ///
    /// Should be called before `GetNavigationController` to ensure that it is applied to all
    /// navigations including the first [`NavigationController.LoadURL`] request.
    SetNavigationPolicyProvider(resource struct {
        params NavigationPolicyProviderParams;
        provider client_end:NavigationPolicyProvider;
    });

    /// Specifies the color theme reported to web content via the `prefers-color-scheme` media
    /// query.
    /// Valid inputs are `LIGHT`, `DARK`, and `DEFAULT`. Each Frame starts with LIGHT theme.
    /// Specifying `DEFAULT` means using the system settings, and requires that the [`Context`] have
    /// the [`fuchsia.settings.Display`] service. If the service is not available, the [`Frame`]
    /// will disconnect with `ZX_ERR_INVALID_ARGS`.
    @deprecated("use fuchsia.web.SetContentAreaSettings instead")
    SetPreferredTheme(struct {
        theme fuchsia.settings.ThemeType;
    });

    /// Sets scale factor (zoom level) that should be applied to web content rendered in this
    /// frame. Values above 1.0 make all web content (including text and images) larger, while
    /// values below 1.0 will make it smaller. In other words, values above 1.0 are used to zoom in
    /// and values below 1.0 zoom out. The overall ratio between physical pixel and CSS pixel is a
    /// product of the scale set with this method and the scale provided by Scenic (see
    /// [`fuchsia.ui.gfx.Metrics`]). That product is visible to the web content as
    /// `window.devicePixelRatio`.
    ///
    /// This method does not have any effect on the size of the view on the screen and the
    /// resolution at which the view is rendered. Native (non-web) UI elements, such as default
    /// scroll bars and default mouse cursor, are not scaled. User may zoom the page further when
    /// pinch-zoom is enabled (see [`InputTypes.GESTURE_PINCH`]).
    @deprecated("use fuchsia.web.SetContentAreaSettings instead")
    SetPageScale(struct {
        scale float32;
    });

    /// Sets various settings for how web content should be run in the Frame. May be called at any
    /// time, including after the URL has loaded. Each call to SetContentAreaSettings() changes
    /// only the specified fields, overwriting any prior value.
    ///
    /// This method will fail with `ZX_ERR_NOT_SUPPORTED` if any value in [`ContentAreaSettings`]
    /// is not supported by the Frame.
    @transitional
    SetContentAreaSettings(struct {
        settings ContentAreaSettings;
    });

    /// Reset the Frame's |ContentAreaSettings| to default values.
    @transitional
    ResetContentAreaSettings();
};

type WebMessage = resource table {
    /// The message payload, encoded as an UTF-8 string. This is a required property.
    1: data fuchsia.mem.Buffer;

    /// Optional list of objects transferred into the [`MessagePort`] from the FIDL client.
    2: incoming_transfer vector<IncomingTransferable>:MAX;

    /// Optional list of objects transferred out of the [`MessagePort`] to the FIDL client.
    3: outgoing_transfer vector<OutgoingTransferable>:MAX;
};

type OutgoingTransferable = flexible resource union {
    1: message_port server_end:MessagePort;
};

type IncomingTransferable = flexible resource union {
    1: message_port client_end:MessagePort;
};

/// Represents one end of an HTML5 MessageChannel. Can be used to send and exchange Messages with
/// the peered MessagePort in the Frame's script context. The port is destroyed when either end of
/// the MessagePort channel is torn down.
protocol MessagePort {
    /// Sends a [`WebMessage`] to the peer. These are processed in order, one at a
    /// time. It is not necessary for the caller to wait for the completion callback before calling
    /// [`MessagePort.PostMessage`] again.
    ///
    /// If an error occured, the [`FrameError`] will be set to one of these value:
    /// - `BUFFER_NOT_UTF8`: The script in `message`'s `data` property is not UTF-8 encoded.
    /// - `NO_DATA_IN_MESSAGE`: The `data` property is missing in `message`.
    PostMessage(resource struct {
        message WebMessage;
    }) -> (struct {}) error FrameError;

    /// Asynchronously reads the next message from the channel. The client should invoke the
    /// callback when it is ready to process another message. Unreceived messages are buffered
    /// on the sender's side and bounded by its available resources.
    ReceiveMessage() -> (resource struct {
        message WebMessage;
    });
};

/// Specifies additional information about a newly created popup frame.
type PopupFrameCreationInfo = resource table {
    /// The URL to which the popup frame was initially navigated.
    1: initial_url Url;

    /// Set if the popup frame was created in response to UI interaction from the user (e.g. a
    /// link was clicked).
    2: initiated_by_user bool;
};

protocol PopupFrameCreationListener {
    /// Called when a [`Frame`] has created a new popup `frame`. Information about the popup frame,
    /// and how it was created, is provided via `info`. Additional popup frames are delivered after
    /// the acknowledgement callback is invoked.
    OnPopupFrameCreated(resource struct {
        frame client_end:Frame;
        info PopupFrameCreationInfo;
    }) -> ();
};

/// Flags clients can set when connecting a [`NavigationEventListener`] to indicates interest in
/// optional features.
type NavigationEventListenerFlags = strict bits : uint64 {
    /// Enables `favicon` field in [`NavigationState`].
    FAVICON = 0x1;
};

/// Args for Frame.CreateView2(), see above.
type CreateView2Args = resource table {
    /// Non-optional. This token is provided to attach the client's Flatland view to the parent's
    /// viewport.
    1: view_creation_token fuchsia.ui.views.ViewCreationToken;
};
