// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart' show AndroidViewSurface;

import 'android_webview.pigeon.dart';
import 'android_webview_api_impls.dart';

// TODO(bparrishMines): This can be removed once pigeon supports null values: https://github.com/flutter/flutter/issues/59118
// Workaround to represent null Strings since pigeon doesn't support null
// values.
const String _nullStringIdentifier = '<null-value>';

/// An Android View that displays web pages.
///
/// **Basic usage**
/// In most cases, we recommend using a standard web browser, like Chrome, to
/// deliver content to the user. To learn more about web browsers, read the
/// guide on invoking a browser with
/// [url_launcher](https://pub.dev/packages/url_launcher).
///
/// WebView objects allow you to display web content as part of your widget
/// layout, but lack some of the features of fully-developed browsers. A WebView
/// is useful when you need increased control over the UI and advanced
/// configuration options that will allow you to embed web pages in a
/// specially-designed environment for your app.
///
/// To learn more about WebView and alternatives for serving web content, read
/// the documentation on
/// [Web-based content](https://developer.android.com/guide/webapps).
///
/// When a [WebView] is no longer needed [release] must be called.
class WebView {
  /// Constructs a new WebView.
  WebView({this.useHybridComposition = false}) {
    api.createFromInstance(this);
  }

  /// Pigeon Host Api implementation for [WebView].
  @visibleForTesting
  static WebViewHostApiImpl api = WebViewHostApiImpl();

  WebViewClient? _currentWebViewClient;

  /// Whether the [WebView] will be rendered with an [AndroidViewSurface].
  ///
  /// This implementation uses hybrid composition to render the WebView Widget.
  /// This comes at the cost of some performance on Android versions below 10.
  /// See
  /// https://flutter.dev/docs/development/platform-integration/platform-views#performance
  /// for more information.
  ///
  /// Defaults to false.
  final bool useHybridComposition;

  /// The [WebSettings] object used to control the settings for this WebView.
  late final WebSettings settings = WebSettings(this);

  /// Enables debugging of web contents (HTML / CSS / JavaScript) loaded into any WebViews of this application.
  ///
  /// This flag can be enabled in order to facilitate debugging of web layouts
  /// and JavaScript code running inside WebViews. Please refer to [WebView]
  /// documentation for the debugging guide. The default is false.
  static Future<void> setWebContentsDebuggingEnabled(bool enabled) {
    return api.setWebContentsDebuggingEnabled(enabled);
  }

  /// Loads the given data into this WebView using a 'data' scheme URL.
  ///
  /// Note that JavaScript's same origin policy means that script running in a
  /// page loaded using this method will be unable to access content loaded
  /// using any scheme other than 'data', including 'http(s)'. To avoid this
  /// restriction, use [loadDataWithBaseURL()] with an appropriate base URL.
  ///
  /// The [encoding] parameter specifies whether the data is base64 or URL
  /// encoded. If the data is base64 encoded, the value of the encoding
  /// parameter must be `'base64'`. HTML can be encoded with
  /// `base64.encode(bytes)` like so:
  /// ```dart
  /// import 'dart:convert';
  ///
  /// final unencodedHtml = '''
  ///   <html><body>'%28' is the code for '('</body></html>
  /// ''';
  /// final encodedHtml = base64.encode(utf8.encode(unencodedHtml));
  /// print(encodedHtml);
  /// ```
  ///
  /// The [mimeType] parameter specifies the format of the data. If WebView
  /// can't handle the specified MIME type, it will download the data. If
  /// `null`, defaults to 'text/html'.
  Future<void> loadData({
    required String data,
    String? mimeType,
    String? encoding,
  }) {
    return api.loadDataFromInstance(
      this,
      data,
      mimeType ?? _nullStringIdentifier,
      encoding ?? _nullStringIdentifier,
    );
  }

  /// Loads the given data into this WebView.
  ///
  /// The [baseUrl] is used as base URL for the content. It is used  both to
  /// resolve relative URLs and when applying JavaScript's same origin policy.
  ///
  /// The [historyUrl] is used for the history entry.
  ///
  /// The [mimeType] parameter specifies the format of the data. If WebView
  /// can't handle the specified MIME type, it will download the data. If
  /// `null`, defaults to 'text/html'.
  ///
  /// Note that content specified in this way can access local device files (via
  /// 'file' scheme URLs) only if baseUrl specifies a scheme other than 'http',
  /// 'https', 'ftp', 'ftps', 'about' or 'javascript'.
  ///
  /// If the base URL uses the data scheme, this method is equivalent to calling
  /// [loadData] and the [historyUrl] is ignored, and the data will be treated
  /// as part of a data: URL, including the requirement that the content be
  /// URL-encoded or base64 encoded. If the base URL uses any other scheme, then
  /// the data will be loaded into the WebView as a plain string (i.e. not part
  /// of a data URL) and any URL-encoded entities in the string will not be
  /// decoded.
  ///
  /// Note that the [baseUrl] is sent in the 'Referer' HTTP header when
  /// requesting subresources (images, etc.) of the page loaded using this
  /// method.
  ///
  /// If a valid HTTP or HTTPS base URL is not specified in [baseUrl], then
  /// content loaded using this method will have a `window.origin` value of
  /// `"null"`. This must not be considered to be a trusted origin by the
  /// application or by any JavaScript code running inside the WebView (for
  /// example, event sources in DOM event handlers or web messages), because
  /// malicious content can also create frames with a null origin. If you need
  /// to identify the main frame's origin in a trustworthy way, you should use a
  /// valid HTTP or HTTPS base URL to set the origin.
  Future<void> loadDataWithBaseUrl({
    String? baseUrl,
    required String data,
    String? mimeType,
    String? encoding,
    String? historyUrl,
  }) {
    return api.loadDataWithBaseUrlFromInstance(
      this,
      baseUrl ?? _nullStringIdentifier,
      data,
      mimeType ?? _nullStringIdentifier,
      encoding ?? _nullStringIdentifier,
      historyUrl ?? _nullStringIdentifier,
    );
  }

  /// Loads the given URL with additional HTTP headers, specified as a map from name to value.
  ///
  /// Note that if this map contains any of the headers that are set by default
  /// by this WebView, such as those controlling caching, accept types or the
  /// User-Agent, their values may be overridden by this WebView's defaults.
  ///
  /// Also see compatibility note on [evaluateJavascript].
  Future<void> loadUrl(String url, Map<String, String> headers) {
    return api.loadUrlFromInstance(this, url, headers);
  }

  /// Loads the URL with postData using "POST" method into this WebView.
  ///
  /// If url is not a network URL, it will be loaded with [loadUrl] instead, ignoring the postData param.
  Future<void> postUrl(String url, Uint8List data) {
    return api.postUrlFromInstance(this, url, data);
  }

  /// Gets the URL for the current page.
  ///
  /// This is not always the same as the URL passed to
  /// [WebViewClient.onPageStarted] because although the load for that URL has
  /// begun, the current page may not have changed.
  ///
  /// Returns null if no page has been loaded.
  Future<String?> getUrl() async {
    final String result = await api.getUrlFromInstance(this);
    if (result == _nullStringIdentifier) {
      return null;
    }
    return result;
  }

  /// Whether this WebView has a back history item.
  Future<bool> canGoBack() {
    return api.canGoBackFromInstance(this);
  }

  /// Whether this WebView has a forward history item.
  Future<bool> canGoForward() {
    return api.canGoForwardFromInstance(this);
  }

  /// Goes back in the history of this WebView.
  Future<void> goBack() {
    return api.goBackFromInstance(this);
  }

  /// Goes forward in the history of this WebView.
  Future<void> goForward() {
    return api.goForwardFromInstance(this);
  }

  /// Reloads the current URL.
  Future<void> reload() {
    return api.reloadFromInstance(this);
  }

  /// Clears the resource cache.
  ///
  /// Note that the cache is per-application, so this will clear the cache for
  /// all WebViews used.
  Future<void> clearCache(bool includeDiskFiles) {
    return api.clearCacheFromInstance(this, includeDiskFiles);
  }

  // TODO(bparrishMines): Update documentation once addJavascriptInterface is added.
  /// Asynchronously evaluates JavaScript in the context of the currently displayed page.
  ///
  /// If non-null, the returned value will be any result returned from that
  /// execution.
  ///
  /// Compatibility note. Applications targeting Android versions N or later,
  /// JavaScript state from an empty WebView is no longer persisted across
  /// navigations like [loadUrl]. For example, global variables and functions
  /// defined before calling [loadUrl]) will not exist in the loaded page.
  Future<String?> evaluateJavascript(String javascriptString) async {
    final String result = await api.evaluateJavascriptFromInstance(
      this,
      javascriptString,
    );
    if (result == _nullStringIdentifier) {
      return null;
    }
    return result;
  }

  // TODO(bparrishMines): Update documentation when WebViewClient.onReceivedTitle is added.
  /// Gets the title for the current page.
  ///
  /// Returns null if no page has been loaded.
  Future<String?> getTitle() async {
    final String result = await api.getTitleFromInstance(this);
    if (result == _nullStringIdentifier) {
      return null;
    }
    return result;
  }

  // TODO(bparrishMines): Update documentation when onScrollChanged is added.
  /// Set the scrolled position of your view.
  Future<void> scrollTo(int x, int y) {
    return api.scrollToFromInstance(this, x, y);
  }

  // TODO(bparrishMines): Update documentation when onScrollChanged is added.
  /// Move the scrolled position of your view.
  Future<void> scrollBy(int x, int y) {
    return api.scrollByFromInstance(this, x, y);
  }

  /// Return the scrolled left position of this view.
  ///
  /// This is the left edge of the displayed part of your view. You do not
  /// need to draw any pixels farther left, since those are outside of the frame
  /// of your view on screen.
  Future<int> getScrollX() {
    return api.getScrollXFromInstance(this);
  }

  /// Return the scrolled top position of this view.
  ///
  /// This is the top edge of the displayed part of your view. You do not need
  /// to draw any pixels above it, since those are outside of the frame of your
  /// view on screen.
  Future<int> getScrollY() {
    return api.getScrollYFromInstance(this);
  }

  /// Sets the [WebViewClient] that will receive various notifications and requests.
  ///
  /// This will replace the current handler.
  Future<void> setWebViewClient(WebViewClient webViewClient) {
    _currentWebViewClient = webViewClient;
    WebViewClient.api.createFromInstance(webViewClient);
    return api.setWebViewClientFromInstance(this, webViewClient);
  }

  /// Injects the supplied [JavascriptChannel] into this WebView.
  ///
  /// The object is injected into all frames of the web page, including all the
  /// iframes, using the supplied name. This allows the object's methods to
  /// be accessed from JavaScript.
  ///
  /// Note that injected objects will not appear in JavaScript until the page is
  /// next (re)loaded. JavaScript should be enabled before injecting the object.
  /// For example:
  ///
  /// ```dart
  /// webview.settings.setJavaScriptEnabled(true);
  /// webView.addJavascriptChannel(JavScriptChannel("injectedObject"));
  /// webView.loadUrl("about:blank", <String, String>{});
  /// webView.loadUrl("javascript:injectedObject.postMessage("Hello, World!")", <String, String>{});
  /// ```
  ///
  /// **Important**
  /// * Because the object is exposed to all the frames, any frame could obtain
  /// the object name and call methods on it. There is no way to tell the
  /// calling frame's origin from the app side, so the app must not assume that
  /// the caller is trustworthy unless the app can guarantee that no third party
  /// content is ever loaded into the WebView even inside an iframe.
  Future<void> addJavaScriptChannel(JavaScriptChannel javaScriptChannel) {
    JavaScriptChannel.api.createFromInstance(javaScriptChannel);
    return api.addJavaScriptChannelFromInstance(this, javaScriptChannel);
  }

  /// Removes a previously injected [JavaScriptChannel] from this WebView.
  ///
  /// Note that the removal will not be reflected in JavaScript until the page
  /// is next (re)loaded. See [addJavaScriptChannel].
  Future<void> removeJavaScriptChannel(JavaScriptChannel javaScriptChannel) {
    JavaScriptChannel.api.createFromInstance(javaScriptChannel);
    return api.removeJavaScriptChannelFromInstance(this, javaScriptChannel);
  }

  /// Registers the interface to be used when content can not be handled by the rendering engine, and should be downloaded instead.
  ///
  /// This will replace the current handler.
  Future<void> setDownloadListener(DownloadListener listener) {
    DownloadListener.api.createFromInstance(listener);
    return api.setDownloadListenerFromInstance(this, listener);
  }

  /// Sets the chrome handler.
  ///
  /// This is an implementation of [WebChromeClient] for use in handling
  /// JavaScript dialogs, favicons, titles, and the progress. This will replace
  /// the current handler.
  Future<void> setWebChromeClient(WebChromeClient client) {
    // WebView requires a WebViewClient because of a bug fix that makes
    // calls to WebViewClient.requestLoading/WebViewClient.urlLoading when a new
    // window is opened. This is to make sure a url opened by `Window.open` has
    // a secure url.
    assert(
      _currentWebViewClient != null,
      "Can't set a WebChromeClient without setting a WebViewClient first.",
    );
    WebChromeClient.api.createFromInstance(client, _currentWebViewClient!);
    return api.setWebChromeClientFromInstance(this, client);
  }

  /// Sets the background color of this WebView.
  Future<void> setBackgroundColor(Color color) {
    return api.setBackgroundColorFromInstance(this, color.value);
  }

  /// Releases all resources used by the [WebView].
  ///
  /// Any methods called after [release] will throw an exception.
  Future<void> release() {
    _currentWebViewClient = null;
    WebSettings.api.disposeFromInstance(settings);
    return api.disposeFromInstance(this);
  }
}

/// Manages cookies globally for all webviews.
class CookieManager {
  CookieManager._();

  static CookieManager? _instance;

  /// Gets the globally set CookieManager instance.
  static CookieManager get instance => _instance ??= CookieManager._();

  /// Setter for the singleton value, for testing purposes only.
  @visibleForTesting
  static set instance(CookieManager value) => _instance = value;

  /// Pigeon Host Api implementation for [CookieManager].
  @visibleForTesting
  static CookieManagerHostApi api = CookieManagerHostApi();

  /// Sets a single cookie (key-value pair) for the given URL. Any existing
  /// cookie with the same host, path and name will be replaced with the new
  /// cookie. The cookie being set will be ignored if it is expired. To set
  /// multiple cookies, your application should invoke this method multiple
  /// times.
  ///
  /// The value parameter must follow the format of the Set-Cookie HTTP
  /// response header defined by RFC6265bis. This is a key-value pair of the
  /// form "key=value", optionally followed by a list of cookie attributes
  /// delimited with semicolons (ex. "key=value; Max-Age=123"). Please consult
  /// the RFC specification for a list of valid attributes.
  ///
  /// Note: if specifying a value containing the "Secure" attribute, url must
  /// use the "https://" scheme.
  ///
  /// Params:
  /// url – the URL for which the cookie is to be set
  /// value – the cookie as a string, using the format of the 'Set-Cookie' HTTP response header
  Future<void> setCookie(String url, String value) => api.setCookie(url, value);

  /// Removes all cookies.
  ///
  /// The returned future resolves to true if any cookies were removed.
  Future<bool> clearCookies() => api.clearCookies();
}

/// Manages settings state for a [WebView].
///
/// When a WebView is first created, it obtains a set of default settings. These
/// default settings will be returned from any getter call. A WebSettings object
/// obtained from [WebView.settings] is tied to the life of the WebView. If a
/// WebView has been destroyed, any method call on [WebSettings] will throw an
/// Exception.
class WebSettings {
  /// Constructs a [WebSettings].
  ///
  /// This constructor is only used for testing. An instance should be obtained
  /// with [WebView.settings].
  @visibleForTesting
  WebSettings(WebView webView) {
    api.createFromInstance(this, webView);
  }

  /// Pigeon Host Api implementation for [WebSettings].
  @visibleForTesting
  static WebSettingsHostApiImpl api = WebSettingsHostApiImpl();

  /// Sets whether the DOM storage API is enabled.
  ///
  /// The default value is false.
  Future<void> setDomStorageEnabled(bool flag) {
    return api.setDomStorageEnabledFromInstance(this, flag);
  }

  /// Tells JavaScript to open windows automatically.
  ///
  /// This applies to the JavaScript function `window.open()`. The default is
  /// false.
  Future<void> setJavaScriptCanOpenWindowsAutomatically(bool flag) {
    return api.setJavaScriptCanOpenWindowsAutomaticallyFromInstance(
      this,
      flag,
    );
  }

  // TODO(bparrishMines): Update documentation when WebChromeClient.onCreateWindow is added.
  /// Sets whether the WebView should supports multiple windows.
  ///
  /// The default is false.
  Future<void> setSupportMultipleWindows(bool support) {
    return api.setSupportMultipleWindowsFromInstance(this, support);
  }

  /// Tells the WebView to enable JavaScript execution.
  ///
  /// The default is false.
  Future<void> setJavaScriptEnabled(bool flag) {
    return api.setJavaScriptEnabledFromInstance(this, flag);
  }

  /// Sets the WebView's user-agent string.
  ///
  /// If the string is empty, the system default value will be used. Note that
  /// starting from KITKAT Android version, changing the user-agent while
  /// loading a web page causes WebView to initiate loading once again.
  Future<void> setUserAgentString(String userAgentString) {
    return api.setUserAgentStringFromInstance(this, userAgentString);
  }

  /// Sets whether the WebView requires a user gesture to play media.
  ///
  /// The default is true.
  Future<void> setMediaPlaybackRequiresUserGesture(bool require) {
    return api.setMediaPlaybackRequiresUserGestureFromInstance(this, require);
  }

  // TODO(bparrishMines): Update documentation when WebView.zoomIn and WebView.zoomOut are added.
  /// Sets whether the WebView should support zooming using its on-screen zoom controls and gestures.
  ///
  /// The particular zoom mechanisms that should be used can be set with
  /// [setBuiltInZoomControls].
  ///
  /// The default is true.
  Future<void> setSupportZoom(bool support) {
    return api.setSupportZoomFromInstance(this, support);
  }

  /// Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width.
  ///
  /// This setting is taken into account when the content width is greater than
  /// the width of the WebView control, for example, when [setUseWideViewPort]
  /// is enabled.
  ///
  /// The default is false.
  Future<void> setLoadWithOverviewMode(bool overview) {
    return api.setLoadWithOverviewModeFromInstance(this, overview);
  }

  /// Sets whether the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport.
  ///
  /// When the value of the setting is false, the layout width is always set to
  /// the width of the WebView control in device-independent (CSS) pixels. When
  /// the value is true and the page contains the viewport meta tag, the value
  /// of the width specified in the tag is used. If the page does not contain
  /// the tag or does not provide a width, then a wide viewport will be used.
  Future<void> setUseWideViewPort(bool use) {
    return api.setUseWideViewPortFromInstance(this, use);
  }

  // TODO(bparrishMines): Update documentation when ZoomButtonsController is added.
  /// Sets whether the WebView should display on-screen zoom controls when using the built-in zoom mechanisms.
  ///
  /// See [setBuiltInZoomControls]. The default is true. However, on-screen zoom
  /// controls are deprecated in Android so it's recommended to set this to
  /// false.
  Future<void> setDisplayZoomControls(bool enabled) {
    return api.setDisplayZoomControlsFromInstance(this, enabled);
  }

  // TODO(bparrishMines): Update documentation when ZoomButtonsController is added.
  /// Sets whether the WebView should use its built-in zoom mechanisms.
  ///
  /// The built-in zoom mechanisms comprise on-screen zoom controls, which are
  /// displayed over the WebView's content, and the use of a pinch gesture to
  /// control zooming. Whether or not these on-screen controls are displayed can
  /// be set with [setDisplayZoomControls]. The default is false.
  ///
  /// The built-in mechanisms are the only currently supported zoom mechanisms,
  /// so it is recommended that this setting is always enabled. However,
  /// on-screen zoom controls are deprecated in Android so it's recommended to
  /// disable [setDisplayZoomControls].
  Future<void> setBuiltInZoomControls(bool enabled) {
    return api.setBuiltInZoomControlsFromInstance(this, enabled);
  }
}

/// Exposes a channel to receive calls from javaScript.
///
/// See [WebView.addJavaScriptChannel].
abstract class JavaScriptChannel {
  /// Constructs a [JavaScriptChannel].
  JavaScriptChannel(this.channelName) {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// Pigeon Host Api implementation for [JavaScriptChannel].
  @visibleForTesting
  static JavaScriptChannelHostApiImpl api = JavaScriptChannelHostApiImpl();

  /// Used to identify this object to receive messages from javaScript.
  final String channelName;

  /// Callback method when javaScript calls `postMessage` on the object instance passed.
  void postMessage(String message);
}

/// Receive various notifications and requests for [WebView].
abstract class WebViewClient {
  /// Constructs a [WebViewClient].
  WebViewClient({this.shouldOverrideUrlLoading = true}) {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// User authentication failed on server.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_AUTHENTICATION
  static const int errorAuthentication = -4;

  /// Malformed URL.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_BAD_URL
  static const int errorBadUrl = -12;

  /// Failed to connect to the server.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_CONNECT
  static const int errorConnect = -6;

  /// Failed to perform SSL handshake.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FAILED_SSL_HANDSHAKE
  static const int errorFailedSslHandshake = -11;

  /// Generic file error.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FILE
  static const int errorFile = -13;

  /// File not found.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FILE_NOT_FOUND
  static const int errorFileNotFound = -14;

  /// Server or proxy hostname lookup failed.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_HOST_LOOKUP
  static const int errorHostLookup = -2;

  /// Failed to read or write to the server.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_IO
  static const int errorIO = -7;

  /// User authentication failed on proxy.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_PROXY_AUTHENTICATION
  static const int errorProxyAuthentication = -5;

  /// Too many redirects.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_REDIRECT_LOOP
  static const int errorRedirectLoop = -9;

  /// Connection timed out.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_TIMEOUT
  static const int errorTimeout = -8;

  /// Too many requests during this load.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_TOO_MANY_REQUESTS
  static const int errorTooManyRequests = -15;

  /// Generic error.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNKNOWN
  static const int errorUnknown = -1;

  /// Resource load was canceled by Safe Browsing.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSAFE_RESOURCE
  static const int errorUnsafeResource = -16;

  /// Unsupported authentication scheme (not basic or digest).
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSUPPORTED_AUTH_SCHEME
  static const int errorUnsupportedAuthScheme = -3;

  /// Unsupported URI scheme.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSUPPORTED_SCHEME
  static const int errorUnsupportedScheme = -10;

  /// Pigeon Host Api implementation for [WebViewClient].
  @visibleForTesting
  static WebViewClientHostApiImpl api = WebViewClientHostApiImpl();

  /// Whether loading a url should be overridden.
  ///
  /// In Java, `shouldOverrideUrlLoading()` and `shouldOverrideRequestLoading()`
  /// callbacks must synchronously return a boolean. This sets the default
  /// return value.
  ///
  /// Setting [shouldOverrideUrlLoading] to true causes the current [WebView] to
  /// abort loading the URL, while returning false causes the [WebView] to
  /// continue loading the URL as usual. [requestLoading] or [urlLoading] will
  /// still be called either way.
  ///
  /// Defaults to true.
  final bool shouldOverrideUrlLoading;

  /// Notify the host application that a page has started loading.
  ///
  /// This method is called once for each main frame load so a page with iframes
  /// or framesets will call onPageStarted one time for the main frame. This
  /// also means that [onPageStarted] will not be called when the contents of an
  /// embedded frame changes, i.e. clicking a link whose target is an iframe, it
  /// will also not be called for fragment navigations (navigations to
  /// #fragment_id).
  void onPageStarted(WebView webView, String url) {}

  // TODO(bparrishMines): Update documentation when WebView.postVisualStateCallback is added.
  /// Notify the host application that a page has finished loading.
  ///
  /// This method is called only for main frame. Receiving an [onPageFinished]
  /// callback does not guarantee that the next frame drawn by WebView will
  /// reflect the state of the DOM at this point.
  void onPageFinished(WebView webView, String url) {}

  /// Report web resource loading error to the host application.
  ///
  /// These errors usually indicate inability to connect to the server. Note
  /// that unlike the deprecated version of the callback, the new version will
  /// be called for any resource (iframe, image, etc.), not just for the main
  /// page. Thus, it is recommended to perform minimum required work in this
  /// callback.
  void onReceivedRequestError(
    WebView webView,
    WebResourceRequest request,
    WebResourceError error,
  ) {}

  /// Report an error to the host application.
  ///
  /// These errors are unrecoverable (i.e. the main resource is unavailable).
  /// The errorCode parameter corresponds to one of the error* constants.
  @Deprecated('Only called on Android version < 23.')
  void onReceivedError(
    WebView webView,
    int errorCode,
    String description,
    String failingUrl,
  ) {}

  // TODO(bparrishMines): Update documentation once synchronous url handling is supported.
  /// When a URL is about to be loaded in the current [WebView].
  ///
  /// If a [WebViewClient] is not provided, by default [WebView] will ask
  /// Activity Manager to choose the proper handler for the URL. If a
  /// [WebViewClient] is provided, setting [shouldOverrideUrlLoading] to true
  /// causes the current [WebView] to abort loading the URL, while returning
  /// false causes the [WebView] to continue loading the URL as usual.
  void requestLoading(WebView webView, WebResourceRequest request) {}

  // TODO(bparrishMines): Update documentation once synchronous url handling is supported.
  /// When a URL is about to be loaded in the current [WebView].
  ///
  /// If a [WebViewClient] is not provided, by default [WebView] will ask
  /// Activity Manager to choose the proper handler for the URL. If a
  /// [WebViewClient] is provided, setting [shouldOverrideUrlLoading] to true
  /// causes the current [WebView] to abort loading the URL, while returning
  /// false causes the [WebView] to continue loading the URL as usual.
  void urlLoading(WebView webView, String url) {}
}

/// The interface to be used when content can not be handled by the rendering engine for [WebView], and should be downloaded instead.
abstract class DownloadListener {
  /// Constructs a [DownloadListener].
  DownloadListener() {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// Pigeon Host Api implementation for [DownloadListener].
  @visibleForTesting
  static DownloadListenerHostApiImpl api = DownloadListenerHostApiImpl();

  /// Notify the host application that a file should be downloaded.
  void onDownloadStart(
    String url,
    String userAgent,
    String contentDisposition,
    String mimetype,
    int contentLength,
  );
}

/// Handles JavaScript dialogs, favicons, titles, and the progress for [WebView].
abstract class WebChromeClient {
  /// Constructs a [WebChromeClient].
  WebChromeClient() {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// Pigeon Host Api implementation for [WebChromeClient].
  @visibleForTesting
  static WebChromeClientHostApiImpl api = WebChromeClientHostApiImpl();

  /// Notify the host application that a file should be downloaded.
  void onProgressChanged(WebView webView, int progress) {}
}

/// Encompasses parameters to the [WebViewClient.requestLoading] method.
class WebResourceRequest {
  /// Constructs a [WebResourceRequest].
  WebResourceRequest({
    required this.url,
    required this.isForMainFrame,
    required this.isRedirect,
    required this.hasGesture,
    required this.method,
    required this.requestHeaders,
  });

  /// The URL for which the resource request was made.
  final String url;

  /// Whether the request was made in order to fetch the main frame's document.
  final bool isForMainFrame;

  /// Whether the request was a result of a server-side redirect.
  ///
  /// Only supported on Android version >= 24.
  final bool? isRedirect;

  /// Whether a gesture (such as a click) was associated with the request.
  final bool hasGesture;

  /// The method associated with the request, for example "GET".
  final String method;

  /// The headers associated with the request.
  final Map<String, String> requestHeaders;
}

/// Encapsulates information about errors occurred during loading of web resources.
///
/// See [WebViewClient.onReceivedRequestError].
class WebResourceError {
  /// Constructs a [WebResourceError].
  WebResourceError({
    required this.errorCode,
    required this.description,
  });

  /// The integer code of the error (e.g. [WebViewClient.errorAuthentication].
  final int errorCode;

  /// Describes the error.
  final String description;
}

/// Manages Flutter assets that are part of Android's app bundle.
class FlutterAssetManager {
  /// Constructs the [FlutterAssetManager].
  const FlutterAssetManager();

  /// Pigeon Host Api implementation for [FlutterAssetManager].
  @visibleForTesting
  static FlutterAssetManagerHostApi api = FlutterAssetManagerHostApi();

  /// Lists all assets at the given path.
  ///
  /// The assets are returned as a `List<String>`. The `List<String>` only
  /// contains files which are direct childs
  Future<List<String?>> list(String path) => api.list(path);

  /// Gets the relative file path to the Flutter asset with the given name.
  Future<String> getAssetFilePathByName(String name) =>
      api.getAssetFilePathByName(name);
}
