// 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.media.sessions2;
using fuchsia.mem;
using fuchsia.ui.gfx;
using fuchsia.ui.views;

// TODO(fxb/29927): Consider using [`fuchsia.logger.LogLevelFilter`] if possible.
enum ConsoleLogLevel : 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.
bits InputTypes : 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 ConfigureInputTypes() should allow or deny processing of
/// the specified [`fuchsia.web.InputTypes`].
enum AllowInputState : int32 {
    ALLOW = 1;
    DENY = 2;
};

/// Represents the return status of a [`fuchsia.web.Frame`] method.
enum FrameError : 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 [`fuchsia.web.WebMessage`].
    NO_DATA_IN_MESSAGE = 4;
};

/// Identifies a type of permission that may be granted to a web origin.
enum PermissionType : 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.
table PermissionDescriptor {
    1: PermissionType type;
};

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

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

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/token`] to attach the new view to a view tree.
    ///
    /// - `view_token`: Token for the new view.
    CreateView(fuchsia.ui.views.ViewToken view_token);

    /// 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.
    [Transitional]
    EnableHeadlessRendering();

    /// Stops headless rendering of the Frame.
    /// May only be used on a Context created with the `HEADLESS` feature flag.
    [Transitional]
    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 [`fuchsia.web.Frame`].
    [Transitional]
    GetMediaPlayer(request<fuchsia.media.sessions2.Player> player);

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

    /// Executes a UTF-8 encoded `script` in the [`fuchsia.web.Frame`] if the
    /// [`fuchsia.web.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 [`fuchsia.web.Frame`]'s current URL does not match any of the
    ///    values in `origins` or `origins` is an empty vector.
    // TODO(crbug.com/900391): Investigate if we can run the scripts in isolated JS worlds.
    ExecuteJavaScript(
        vector<Url> origins,
        fuchsia.mem.Buffer script)
        -> (fuchsia.mem.Buffer result) error FrameError;

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

    /// Executes a UTF-8 encoded `script` for every subsequent page load where the
    /// [`fuchsia.web.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 [`fuchsia.web.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(
        uint64 id,
        vector<Url> origins,
        fuchsia.mem.Buffer script)
        -> () 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(uint64 id);

    /// 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
    /// [https://html.spec.whatwg.org/multipage/web-messaging.html#posting-messages](HTML spec)
    /// section 9.4.3 for more details on how the target origin policy is applied.
    ///
    /// If an error occured, the [`fuchsia.web.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(Url target_origin, WebMessage message)
        -> () error FrameError;

    /// Sets the listener for handling page navigation events.
    ///
    /// - `listener`: The observer to use. Unregisters any existing listener is null.
    SetNavigationEventListener(NavigationEventListener? listener);

    /// If set to a value other than [`fuchsia.web.ConsoleLogLevel/NONE`], allows web content to
    /// log messages to the system logger using the console APIs (`debug()`, `log()`, `info()`,
    /// `warn()` and `error()`).
    /// The default value is [`fuchsia.web.ConsoleLogLevel/NONE`].
    ///
    /// As the system log may be persisted, it is recommended that
    /// [`fuchsia.web.ConsoleLogLevel/NONE`] be used in Incognito and other private browsing modes.
    ///
    /// When logged to the system logger:
    /// - `debug()`, `log()` and `info()` logs are logged with
    ///   [`fuchsia.logger.LogLevelFilter/INFO`] severity level.
    /// - `warn()` logs are logged with [`fuchsia.logger.LogLevelFilter/WARNING`] severity level.
    /// - `error()` logs are logged with [`fuchsia.logger.LogLevelFilter/ERROR`] severity level.
    SetJavaScriptLogLevel(ConsoleLogLevel level);

    [Transitional, Deprecated]
    SetEnableInput(bool enable_input);

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

    /// 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(PopupFrameCreationListener? listener);

    /// Supplies a set of [`fuchsia.web.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
    ///   [`fuchsia.web.Frame`] will be closed with `ERR_INVALID_ARGS`.
    /// - [`fuchsia.web.Frame/SetUrlRequestRewriteRules`] must not be called again until its
    ///   acknowledgement callback has been processed. If this happens, the [`fuchsia.web.Frame`]
    ///   will be closed with `ERR_BAD_STATE`.
    SetUrlRequestRewriteRules(vector<UrlRequestRewriteRule>:MAX_RULE_COUNT rules) -> ();

    /// 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 [`fuchsia.web.Frame/GetNavigationController`].
    [Transitional]
    SetMediaSessionId(uint64 session_id);

    /// 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.
    [Transitional]
    ForceContentDimensions(fuchsia.ui.gfx.vec2? web_dips);

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

    /// 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.
    [Transitional]
    SetBlockMediaLoading(bool blocked);
};

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

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

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

flexible union OutgoingTransferable {
    1: request<MessagePort> message_port;
};

flexible union IncomingTransferable {
    1: MessagePort message_port;
};

/// 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 [`fuchsia.web.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
    /// [`fuchsia.web.MessagePort/PostMessage`] again.
    ///
    /// If an error occured, the [`fuchsia.web.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(WebMessage message) -> () 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() -> (WebMessage message);
};

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

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

protocol PopupFrameCreationListener {
    /// Called when a [`fuchsia.web.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 the acknowledgement callback is invoked.
    OnPopupFrameCreated(Frame frame, PopupFrameCreationInfo info) -> ();
};
