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

// TODO(yjbanov): rename this file to web_only_api.dart.
//                https://github.com/flutter/flutter/issues/100394
//                Rather than extending this file with new APIs, we
//                should instead use js interop.

// This file contains extra web-only API that non-web engines do not have.
//
// Why have web-only API?
//
// Because all Dart code is compiled (and tree shaken) as a single compilation
// unit it only has one entry-point - the `main()` function of the Flutter
// app. The top-level `main()` is generated by Flutter tool and it needs to
// ask the engine to initialize itself before calling the handwritten `main()`
// function of the app itself. To do that, it needs something to call. The
// mobile engine doesn't provide a function like that because the application
// starts from the Java (Android) or Objective-C (iOS). Any initial
// configuration can be done in Java and the engine's C++ code prior to
// calling Dart's `main()`.

part of ui;

/// Performs one-time initialization of the web environment that supports the
/// Flutter framework.
///
/// This is only available on the Web, as native Flutter configures the
/// environment in the native embedder.
Future<void> webOnlyInitializePlatform() async {
  await engine.initializeEngine();
}

/// Initializes essential bits of the engine before it fully initializes.
/// When [didCreateEngineInitializer] is set, it delegates engine initialization
/// and app startup to the programmer.
/// Else, it immediately triggers the full engine + app bootstrap.
///
/// This method is called by the flutter_tools package, from the entrypoint that
/// it generates around the main method provided by the programmer. See:
/// * https://github.com/flutter/flutter/blob/2bd3e0d914854aa8c12e933f25c5fd8532ae5571/packages/flutter_tools/lib/src/build_system/targets/web.dart#L135-L163
/// * https://github.com/flutter/flutter/blob/61fb2de52c7bdac19b7f2f74eaf3f11237e1e91d/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart#L460-L485
///
/// This function first calls [engine.initializeEngineServices] so the engine
/// can prepare the js-interop layer that is used by web apps (instead of the
/// old `ui.webOnlyFoo` methods/getters).
///
/// It then creates a JsObject that is passed to the [didCreateEngineInitializer]
/// JS callback, to delegate bootstrapping the app to the programmer.
///
/// If said callback is not defined, this assumes that the Flutter Web app is
/// initializing "automatically", as was normal before this feature was
/// introduced. This will immediately run the initEngine and runApp methods
/// (via [engine.AppBootstrap.now]).
///
/// This is the only bit of `dart:ui` that should be directly called by Flutter
/// web apps. Everything else should go through the JS-interop layer created in
/// `engine.warmup`.
///
/// This method should NOT trigger the download of any additional resources
/// (except when the app is in "autoStart" mode).
Future<void> webOnlyWarmupEngine({
  Function? registerPlugins,
  Function? runApp,
}) async {
  // Create the object that knows how to bootstrap an app from JS and Dart.
  final engine.AppBootstrap bootstrap = engine.AppBootstrap(
    initializeEngine: ([engine.JsFlutterConfiguration? configuration]) async {
      await engine.initializeEngineServices(jsConfiguration: configuration);
    }, runApp: () async {
      if (registerPlugins != null) {
        registerPlugins();
      }
      await engine.initializeEngineUi();
      if (runApp != null) {
        runApp();
      }
    },
  );

  final engine.FlutterLoader? loader = engine.flutter?.loader;
  if (loader == null || loader.isAutoStart) {
    // The user does not want control of the app, bootstrap immediately.
    engine.domWindow.console.debug('Flutter Web Bootstrap: Auto.');
    await bootstrap.autoStart();
  } else {
    // Yield control of the bootstrap procedure to the user.
    engine.domWindow.console.debug('Flutter Web Bootstrap: Programmatic.');
    loader.didCreateEngineInitializer(bootstrap.prepareEngineInitializer());
  }
}

/// Emulates the `flutter test` environment.
///
/// When set to true, the engine will emulate a specific screen size, and always
/// use the "Ahem" font to reduce test flakiness and dependence on the test
/// environment.
bool get debugEmulateFlutterTesterEnvironment =>
    _debugEmulateFlutterTesterEnvironment;
set debugEmulateFlutterTesterEnvironment(bool value) {
  _debugEmulateFlutterTesterEnvironment = value;
  if (_debugEmulateFlutterTesterEnvironment) {
    const Size logicalSize = Size(800.0, 600.0);
    engine.window.webOnlyDebugPhysicalSizeOverride =
        logicalSize * window.devicePixelRatio;
  }
  engine.debugDisableFontFallbacks = value;
}

bool _debugEmulateFlutterTesterEnvironment = false;

/// Provides the asset manager.
// TODO(yjbanov): this function should not return a private type. Instead, we
//                should create a public interface for the returned value that's
//                implemented by the engine.
//                https://github.com/flutter/flutter/issues/100394
engine.AssetManager get webOnlyAssetManager => engine.assetManager;

/// Sets the handler that forwards platform messages to web plugins.
///
/// This function exists because unlike mobile, on the web plugins are also
/// implemented using Dart code, and that code needs a way to receive messages.
void webOnlySetPluginHandler(Future<void> Function(String, ByteData?, PlatformMessageResponseCallback?) handler) {
  engine.pluginMessageCallHandler = handler;
}

/// A registry for factories that create platform views.
class PlatformViewRegistry {
  /// Register [viewTypeId] as being creating by the given [viewFactory].
  /// [viewFactory] can be any function that takes an integer and returns an
  /// `HTMLElement` DOM object.
  bool registerViewFactory(String viewTypeId,
      Object Function(int viewId) viewFactory,
      {bool isVisible = true}) {
    // TODO(web): Deprecate this once there's another way of calling `registerFactory` (js interop?)
    return engine.platformViewManager
        .registerFactory(viewTypeId, viewFactory, isVisible: isVisible);
  }
}

/// The platform view registry for this app.
final PlatformViewRegistry platformViewRegistry = PlatformViewRegistry();
