// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.ffi;

/// Marker interface for objects which should not be finalized too soon.
///
/// Any local variable with a static type that _includes `Finalizable`_
/// is guaranteed to be alive until execution exits the code block where
/// the variable is in scope.
///
/// A type _includes `Finalizable`_ if either
/// * the type is a non-`Never` subtype of `Finalizable`, or
/// * the type is `T?` or `FutureOr<T>` where `T` includes `Finalizable`.
///
/// In other words, while an object is referenced by such a variable,
/// it is guaranteed to *not* be considered unreachable,
/// and the variable itself is considered alive for the entire duration
/// of its scope, even after it is last referenced.
///
/// _Without this marker interface on the variable's type, a variable's
/// value might be garbage collected before the surrounding scope has
/// been completely executed, as long as the variable is definitely not
/// referenced again. That can, in turn, trigger a `NativeFinalizer`
/// to perform a callback. When the variable's type includes [Finalizable],
/// The `NativeFinalizer` callback is prevented from running until
/// the current code using that variable is complete._
///
/// For example, `finalizable` is kept alive during the execution of
/// `someNativeCall`:
///
/// ```dart
/// void myFunction() {
///   final finalizable = MyFinalizable(Pointer.fromAddress(0));
///   someNativeCall(finalizable.nativeResource);
/// }
///
/// void someNativeCall(Pointer nativeResource) {
///   // ..
/// }
///
/// class MyFinalizable implements Finalizable {
///   final Pointer nativeResource;
///
///   MyFinalizable(this.nativeResource);
/// }
/// ```
///
/// Methods on a class implementing `Finalizable` keep the `this` object alive
/// for the duration of the method execution. _The `this` value is treated
/// like a local variable._
///
/// For example, `this` is kept alive during the execution of `someNativeCall`
/// in `myFunction`:
///
/// ```dart
/// class MyFinalizable implements Finalizable {
///   final Pointer nativeResource;
///
///   MyFinalizable(this.nativeResource);
///
///   void myFunction() {
///     someNativeCall(nativeResource);
///   }
/// }
///
/// void someNativeCall(Pointer nativeResource) {
///   // ..
/// }
/// ```
///
/// It is good practise to implement logic involving finalizables as methods
/// on the class that implements [Finalizable].
///
/// If a closure is created inside the block scope declaring the variable, and
/// that closure contains any reference to the variable, the variable stays
/// alive as long as the closure object does, or as long as the body of such a
/// closure is executing.
///
/// For example, `finalizable` is kept alive by the closure object and until the
/// end of the closure body:
///
/// ```dart
/// void doSomething() {
///   final resourceAction = myFunction();
///   resourceAction(); // `finalizable` is alive until this call returns.
/// }
///
/// void Function() myFunction() {
///   final finalizable = MyFinalizable(Pointer.fromAddress(0));
///   return () {
///     someNativeCall(finalizable.nativeResource);
///   };
/// }
///
/// void someNativeCall(Pointer nativeResource) {
///   // ..
/// }
///
/// class MyFinalizable implements Finalizable {
///   final Pointer nativeResource;
///
///   MyFinalizable(this.nativeResource);
/// }
/// ```
///
/// Only captured variables are kept alive by closures, not all variables.
///
/// For example, `finalizable` is not kept alive by the returned closure object:
///
/// ```dart
/// void Function() myFunction() {
///   final finalizable = MyFinalizable(Pointer.fromAddress(0));
///   final nativeResource = finalizable.nativeResource;
///   return () {
///     someNativeCall(nativeResource);
///   };
/// }
///
/// void someNativeCall(Pointer nativeResource) {
///   // ..
/// }
///
/// class MyFinalizable implements Finalizable {
///   final Pointer nativeResource;
///
///   MyFinalizable(this.nativeResource);
/// }
/// ```
///
/// It's likely an error if a resource extracted from a finalizable object
/// escapes the scope of the finalizable variable it's taken from.
///
/// The behavior of `Finalizable` variables applies to asynchronous
/// functions too. Such variables are kept alive as long as any
/// code may still execute inside the scope that declared the variable,
/// or in a closure capturing the variable,
/// even if there are asynchronous delays during that execution.
///
/// For example, `finalizable` is kept alive during the `await someAsyncCall()`:
///
/// ```dart
/// Future<void> myFunction() async {
///   final finalizable = MyFinalizable();
///   await someAsyncCall();
/// }
///
/// Future<void> someAsyncCall() async {
///   // ..
/// }
///
/// class MyFinalizable implements Finalizable {
///   // ..
/// }
/// ```
///
/// Also in asynchronous code it's likely an error if a resource extracted from
/// a finalizable object escapes the scope of the finalizable variable it's
/// taken from. If you have to extract a resource from a `Finalizable`, you
/// should ensure the scope in which Finalizable is defined outlives the
/// resource by `await`ing any asynchronous code that uses the resource.
///
/// For example, `this` is kept alive until `resource` is not used anymore in
/// `useAsync1`, but not in `useAsync2` and `useAsync3`:
///
/// ```dart
/// class MyFinalizable {
///   final Pointer<Int8> resource;
///
///   MyFinalizable(this.resource);
///
///   Future<int> useAsync1() async {
///     return await useResource(resource);
///   }
///
///   Future<int> useAsync2() async {
///     return useResource(resource);
///   }
///
///   Future<int> useAsync3() {
///     return useResource(resource);
///   }
/// }
///
/// /// Does not use [resource] after the returned future completes.
/// Future<int> useResource(Pointer<Int8> resource) async {
///   return resource.value;
/// }
/// ```
///
/// _It is possible for an asynchronous function to *stall* at an
/// `await`, such that the runtime system can see that there is no possible
/// way for that `await` to complete. In that case, no code after the
/// `await` will ever execute, including `finally` blocks, and the
/// variable may be considered dead along with everything else._
///
/// If you're not going to keep a variable alive yourself, make sure to pass the
/// finalizable object to other functions instead of just its resource.
///
/// For example, `finalizable` is not kept alive by `myFunction` after it has
/// run to the end of its scope, while `someAsyncCall` could still continue
/// execution. However, `finalizable` is kept alive by `someAsyncCall` itself:
///
/// ```dart
/// void myFunction() {
///   final finalizable = MyFinalizable();
///   someAsyncCall(finalizable);
/// }
///
/// Future<void> someAsyncCall(MyFinalizable finalizable) async {
///   // ..
/// }
///
/// class MyFinalizable implements Finalizable {
///   // ..
/// }
/// ```
// TODO(http://dartbug.com/44395): Add implicit await to Dart implementation.
// This will fix `useAsync2` above.
@Since('2.17')
abstract class Finalizable {
  factory Finalizable._() => throw UnsupportedError("");
}

/// The native function type for [NativeFinalizer]s.
///
/// A [NativeFinalizer]'s `callback` should have the C
/// `void nativeFinalizer(void* token)` type.
typedef NativeFinalizerFunction
    = NativeFunction<Void Function(Pointer<Void> token)>;

/// A native finalizer which can be attached to Dart objects.
///
/// When [attach]ed to a Dart object, this finalizer's native callback is called
/// after the Dart object is garbage collected or becomes inaccessible for other
/// reasons.
///
/// Callbacks will happen as early as possible, when the object becomes
/// inaccessible to the program, and may happen at any moment during execution
/// of the program. At the latest, when an isolate group shuts down,
/// this callback is guaranteed to be called for each object in that isolate
/// group that the finalizer is still attached to.
///
/// Compared to the [Finalizer] from `dart:core`, which makes no promises to
/// ever call an attached callback, this native finalizer promises that all
/// attached finalizers are definitely called at least once before the program
/// ends, and the callbacks are called as soon as possible after an object
/// is recognized as inaccessible.
///
/// When the callback is a Dart function rather than a native function, use
/// [Finalizer] instead.
///
/// A native finalizer can be used to close native resources. See the following
/// example.
///
/// ```dart
/// /// [Database] enables interacting with the native database.
/// ///
/// /// After [close] is called, cannot be used to [query].
/// ///
/// /// If a [Database] is garbage collected, it is automatically closed by
/// /// means of a native finalizer. Prefer closing manually for timely
/// /// release of native resources.
/// ///
/// /// Note this class is incomplete and for illustration purposes only.
/// class Database implements Finalizable {
///   /// The native finalizer runs [_closeDatabasePointer] on [_nativeDatabase]
///   /// if the object is garbage collected.
///   ///
///   /// Keeps the finalizer itself reachable, otherwise it might be disposed
///   /// before the finalizer callback gets a chance to run.
///   static final _finalizer =
///       NativeFinalizer(_nativeDatabaseBindings.closeDatabaseAddress.cast());
///
///   /// The native resource.
///   ///
///   /// Should be closed exactly once with [_closeDatabase] or
///   /// [_closeDatabasePointer].
///   Pointer<_NativeDatabase> _nativeDatabase;
///
///   /// Used to prevent double close and usage after close.
///   bool _closed = false;
///
///   Database._(this._nativeDatabase);
///
///   /// Open a database.
///   factory Database.open() {
///     final nativeDatabase = _nativeDatabaseBindings.openDatabase();
///     final database = Database._(nativeDatabase);
///     _finalizer.attach(database, nativeDatabase.cast(), detach: database);
///     return database;
///   }
///
///   /// Closes this database.
///   ///
///   /// This database cannot be used anymore after it is closed.
///   void close() {
///     if (_closed) {
///       return;
///     }
///     _closed = true;
///     _finalizer.detach(this);
///     _nativeDatabaseBindings.closeDatabase(_nativeDatabase);
///   }
///
///   /// Query the database.
///   ///
///   /// The database should not have been closed.
///   void query() {
///     if (_closed) {
///       throw StateError('The database has been closed.');
///     }
///
///     // Query the database.
///   }
/// }
///
/// final _nativeDatabaseBindings = _NativeDatabaseLib(DynamicLibrary.process());
///
/// // The following classes are typically generated with `package:ffigen`.
/// // Use `symbol-address` to expose the address of the close function.
/// class _NativeDatabaseLib {
///   final DynamicLibrary _library;
///
///   _NativeDatabaseLib(this._library);
///
///   late final openDatabase = _library.lookupFunction<
///       Pointer<_NativeDatabase> Function(),
///       Pointer<_NativeDatabase> Function()>('OpenDatabase');
///   late final closeDatabaseAddress =
///       _library.lookup<NativeFunction<Void Function(Pointer<_NativeDatabase>)>>(
///           'CloseDatabase');
///   late final closeDatabase = closeDatabaseAddress
///       .asFunction<void Function(Pointer<_NativeDatabase>)>();
/// }
///
/// class _NativeDatabase extends Opaque {}
/// ```
@Since('2.17')
abstract class NativeFinalizer {
  /// Creates a finalizer with the given finalization callback.
  ///
  /// The [callback] must be a native function which can be executed outside of
  /// a Dart isolate. This means that passing an FFI trampoline (a function
  /// pointer obtained via [Pointer.fromFunction]) is not supported.
  ///
  /// The [callback] might be invoked on an arbitrary thread and not necessary
  /// on the same thread that created [NativeFinalizer].
  // TODO(https://dartbug.com/47778): Implement isolate independent code and
  // update the above comment.
  external factory NativeFinalizer(Pointer<NativeFinalizerFunction> callback);

  /// Attaches this finalizer to [value].
  ///
  /// When [value] is no longer accessible to the program,
  /// the finalizer will call its callback function with [token]
  /// as argument.
  ///
  /// If a non-`null` [detach] value is provided, that object can be
  /// passed to [Finalizer.detach] to remove the attachment again.
  ///
  /// The [value] and [detach] arguments do not count towards those
  /// objects being accessible to the program. Both must be objects supported
  /// as an [Expando] key. They may be the *same* object.
  ///
  /// Multiple objects may be using the same finalization token,
  /// and the finalizer can be attached multiple times to the same object
  /// with different, or the same, finalization token.
  ///
  /// The callback will be called exactly once per attachment, except for
  /// registrations which have been detached since they were attached.
  ///
  /// The [externalSize] should represent the amount of native (non-Dart) memory
  /// owned by the given [value]. This information is used for garbage
  /// collection scheduling heuristics.
  void attach(Finalizable value, Pointer<Void> token,
      {Object? detach, int? externalSize});

  /// Detaches this finalizer from values attached with [detach].
  ///
  /// If this finalizer was attached multiple times to the same object with
  /// different detachment keys, only those attachments which used [detach]
  /// are removed.
  ///
  /// After detaching, an attachment won't cause any callbacks to happen if the
  /// object become inaccessible.
  void detach(Object detach);
}
