// 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:async';
import 'dart:developer' as developer;
import 'dart:js_interop';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;

/// The mode the app is running in.
/// Keep these in sync with the same constants on the framework-side under foundation/constants.dart.
const bool kReleaseMode =
    bool.fromEnvironment('dart.vm.product');
/// A constant that is true if the application was compiled in profile mode.
const bool kProfileMode =
    bool.fromEnvironment('dart.vm.profile');
/// A constant that is true if the application was compiled in debug mode.
const bool kDebugMode = !kReleaseMode && !kProfileMode;
/// Returns mode of the app is running in as a string.
String get buildMode => kReleaseMode
    ? 'release'
    : kProfileMode
        ? 'profile'
        : 'debug';

/// A benchmark metric that includes frame-related computations prior to
/// submitting layer and picture operations to the underlying renderer, such as
/// HTML and CanvasKit. During this phase we compute transforms, clips, and
/// other information needed for rendering.
const String kProfilePrerollFrame = 'preroll_frame';

/// A benchmark metric that includes submitting layer and picture information
/// to the renderer.
const String kProfileApplyFrame = 'apply_frame';

final List<ui.VoidCallback> _hotRestartListeners = <ui.VoidCallback>[];

/// Requests that [listener] is called just before hot restarting the app.
void registerHotRestartListener(ui.VoidCallback listener) {
  _hotRestartListeners.add(listener);
}

/// Pretends that hot restart is about to happen.
///
/// Useful in tests to check that the engine performs appropriate clean-ups,
/// such as removing static DOM listeners, prior to allowing the Dart runtime
/// to re-initialize the program.
void debugEmulateHotRestart() {
  for (final ui.VoidCallback listener in _hotRestartListeners) {
    listener();
  }
}

/// Fully initializes the engine, including services and UI.
Future<void> initializeEngine({
  AssetManager? assetManager,
}) async {
  await initializeEngineServices(assetManager: assetManager);
  await initializeEngineUi();
}

/// How far along the initialization process the engine is currently is.
///
/// The initialization process starts with [none] and proceeds in increasing
/// `index` number until [initialized].
enum DebugEngineInitializationState {
  /// Initialization hasn't started yet.
  uninitialized,

  /// The engine is initializing its non-UI services.
  initializingServices,

  /// The engine has initialized its non-UI services, but hasn't started
  /// initializing the UI.
  initializedServices,

  /// The engine started attaching UI surfaces to the web page.
  initializingUi,

  /// The engine has fully completed initialization.
  ///
  /// At this point the framework can start using the engine for I/O, rendering,
  /// etc.
  ///
  /// This is the final state of the engine.
  initialized,
}

/// The current initialization state of the engine.
///
/// See [DebugEngineInitializationState] for possible states.
DebugEngineInitializationState get initializationState => _initializationState;
DebugEngineInitializationState _initializationState = DebugEngineInitializationState.uninitialized;

/// Resets the state back to [DebugEngineInitializationState.uninitialized].
///
/// This is for testing only.
void debugResetEngineInitializationState() {
  _initializationState = DebugEngineInitializationState.uninitialized;
}

/// Initializes non-UI engine services.
///
/// Does not put any UI onto the page. It is therefore safe to call this
/// function while the page is showing non-Flutter UI, such as a loading
/// indicator, a splash screen, or in an add-to-app scenario where the host page
/// is written using a different web framework.
///
/// See also:
///
///  * [initializeEngineUi], which is typically called after this function, and
///    puts UI elements on the page.
Future<void> initializeEngineServices({
  AssetManager? assetManager,
  JsFlutterConfiguration? jsConfiguration
}) async {
  if (_initializationState != DebugEngineInitializationState.uninitialized) {
    assert(() {
      throw StateError(
        'Invalid engine initialization state. `initializeEngineServices` was '
        'called, but the engine has already started initialization and is '
        'currently in state "$_initializationState".'
      );
    }());
    return;
  }
  _initializationState = DebugEngineInitializationState.initializingServices;

  // Store `jsConfiguration` so user settings are available to the engine.
  configuration.setUserConfiguration(jsConfiguration);

  // Setup the hook that allows users to customize URL strategy before running
  // the app.
  _addUrlStrategyListener();

  // Called by the Web runtime just before hot restarting the app.
  //
  // This extension cleans up resources that are registered with browser's
  // global singletons that Dart compiler is unable to clean-up automatically.
  //
  // This extension does not need to clean-up Dart statics. Those are cleaned
  // up by the compiler.
  developer.registerExtension('ext.flutter.disassemble', (_, __) {
    for (final ui.VoidCallback listener in _hotRestartListeners) {
      listener();
    }
    return Future<developer.ServiceExtensionResponse>.value(
        developer.ServiceExtensionResponse.result('OK'));
  });

  if (Profiler.isBenchmarkMode) {
    Profiler.ensureInitialized();
  }

  bool waitingForAnimation = false;
  scheduleFrameCallback = () {
    // We're asked to schedule a frame and call `frameHandler` when the frame
    // fires.
    if (!waitingForAnimation) {
      waitingForAnimation = true;
      domWindow.requestAnimationFrame((JSNumber highResTime) {
        frameTimingsOnVsync();

        // Reset immediately, because `frameHandler` can schedule more frames.
        waitingForAnimation = false;

        // We have to convert high-resolution time to `int` so we can construct
        // a `Duration` out of it. However, high-res time is supplied in
        // milliseconds as a double value, with sub-millisecond information
        // hidden in the fraction. So we first multiply it by 1000 to uncover
        // microsecond precision, and only then convert to `int`.
        final int highResTimeMicroseconds = (1000 * highResTime.toDart).toInt();

        // In Flutter terminology "building a frame" consists of "beginning
        // frame" and "drawing frame".
        //
        // We do not call `frameTimingsOnBuildFinish` from here because
        // part of the rasterization process, particularly in the HTML
        // renderer, takes place in the `SceneBuilder.build()`.
        frameTimingsOnBuildStart();
        if (EnginePlatformDispatcher.instance.onBeginFrame != null) {
          EnginePlatformDispatcher.instance.invokeOnBeginFrame(
              Duration(microseconds: highResTimeMicroseconds));
        }

        if (EnginePlatformDispatcher.instance.onDrawFrame != null) {
          // TODO(yjbanov): technically Flutter flushes microtasks between
          //                onBeginFrame and onDrawFrame. We don't, which hasn't
          //                been an issue yet, but eventually we'll have to
          //                implement it properly.
          EnginePlatformDispatcher.instance.invokeOnDrawFrame();
        }
      });
    }
  };

  assetManager ??= AssetManager(assetBase: configuration.assetBase);
  _setAssetManager(assetManager);

  Future<void> initializeRendererCallback () async => renderer.initialize();
  await Future.wait<void>(<Future<void>>[initializeRendererCallback(), _downloadAssetFonts()]);
  renderer.fontCollection.registerDownloadedFonts();
  _initializationState = DebugEngineInitializationState.initializedServices;
}

/// Initializes the UI surfaces for the Flutter framework to render to.
///
/// Must be called after [initializeEngineServices].
///
/// This function will start altering the HTML structure of the page. If used
/// in an add-to-app scenario, the host page is expected to prepare for Flutter
/// UI appearing on screen prior to calling this function.
Future<void> initializeEngineUi() async {
  if (_initializationState != DebugEngineInitializationState.initializedServices) {
    assert(() {
      throw StateError(
        'Invalid engine initialization state. `initializeEngineUi` was '
        'called while the engine initialization state was '
        '"$_initializationState". `initializeEngineUi` can only be called '
        'when the engine is in state '
        '"${DebugEngineInitializationState.initializedServices}".'
      );
    }());
    return;
  }
  _initializationState = DebugEngineInitializationState.initializingUi;

  initializeAccessibilityAnnouncements();
  RawKeyboard.initialize(onMacOs: operatingSystem == OperatingSystem.macOs);
  MouseCursor.initialize();
  ensureFlutterViewEmbedderInitialized();
  _initializationState = DebugEngineInitializationState.initialized;
}

AssetManager get assetManager => _assetManager!;
AssetManager? _assetManager;

void _setAssetManager(AssetManager assetManager) {
  if (assetManager == _assetManager) {
    return;
  }

  _assetManager = assetManager;
}

Future<void> _downloadAssetFonts() async {
  renderer.fontCollection.clear();

  if (_assetManager != null) {
    await renderer.fontCollection.downloadAssetFonts(_assetManager!);
  }

  if (ui.debugEmulateFlutterTesterEnvironment) {
    await renderer.fontCollection.debugDownloadTestFonts();
  }
}

void _addUrlStrategyListener() {
  jsSetUrlStrategy = allowInterop((JsUrlStrategy? jsStrategy) {
    if (jsStrategy == null) {
      customUrlStrategy = null;
    } else {
      // Because `JSStrategy` could be anything, we check for the
      // `addPopStateListener` property and throw if it is missing.
      if (!hasJsProperty(jsStrategy, 'addPopStateListener')) {
        throw StateError(
            'Unexpected JsUrlStrategy: $jsStrategy is missing '
            '`addPopStateListener` property');
      }
      customUrlStrategy = CustomUrlStrategy.fromJs(jsStrategy);
    }
  });
  registerHotRestartListener(() {
    jsSetUrlStrategy = null;
  });
}

/// Whether to disable the font fallback system.
///
/// We need to disable font fallbacks for some framework tests because
/// Flutter error messages may contain an arrow symbol which is not
/// covered by ASCII fonts. This causes us to try to download the
/// Noto Sans Symbols font, which kicks off a `Timer` which doesn't
/// complete before the Widget tree is disposed (this is by design).
bool get debugDisableFontFallbacks => _debugDisableFontFallbacks;
set debugDisableFontFallbacks(bool value) {
  _debugDisableFontFallbacks = value;
}
bool _debugDisableFontFallbacks = false;

/// The shared instance of PlatformViewManager shared across the engine to handle
/// rendering of PlatformViews into the web app.
// TODO(dit): How to make this overridable from tests?
final PlatformViewManager platformViewManager = PlatformViewManager();
