// Copyright (c) 2019, 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.
//
// Explicit pool used for managing resources.

import "dart:async";
import 'dart:ffi';

import 'package:ffi/ffi.dart';

/// An [Allocator] which frees all allocations at the same time.
///
/// The pool allows you to allocate heap memory, but ignores calls to [free].
/// Instead you call [releaseAll] to release all the allocations at the same
/// time.
///
/// Also allows other resources to be associated with the pool, through the
/// [using] method, to have a release function called for them when the pool is
/// released.
///
/// An [Allocator] can be provided to do the actual allocation and freeing.
/// Defaults to using [calloc].
class Pool implements Allocator {
  /// The [Allocator] used for allocation and freeing.
  final Allocator _wrappedAllocator;

  /// Native memory under management by this [Pool].
  final List<Pointer<NativeType>> _managedMemoryPointers = [];

  /// Callbacks for releasing native resources under management by this [Pool].
  final List<Function()> _managedResourceReleaseCallbacks = [];

  bool _inUse = true;

  /// Creates a pool of allocations.
  ///
  /// The [allocator] is used to do the actual allocation and freeing of
  /// memory. It defaults to using [calloc].
  Pool([Allocator allocator = calloc]) : _wrappedAllocator = allocator;

  /// Allocates memory and includes it in the pool.
  ///
  /// Uses the allocator provided to the [Pool] constructor to do the
  /// allocation.
  ///
  /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
  /// satisfied.
  @override
  Pointer<T> allocate<T extends NativeType>(int byteCount, {int? alignment}) {
    _ensureInUse();
    final p = _wrappedAllocator.allocate<T>(byteCount, alignment: alignment);
    _managedMemoryPointers.add(p);
    return p;
  }

  /// Registers [resource] in this pool.
  ///
  /// Executes [releaseCallback] on [releaseAll].
  T using<T>(T resource, Function(T) releaseCallback) {
    _ensureInUse();
    releaseCallback = Zone.current.bindUnaryCallback(releaseCallback);
    _managedResourceReleaseCallbacks.add(() => releaseCallback(resource));
    return resource;
  }

  /// Registers [releaseResourceCallback] to be executed on [releaseAll].
  void onReleaseAll(Function() releaseResourceCallback) {
    _managedResourceReleaseCallbacks.add(releaseResourceCallback);
  }

  /// Releases all resources that this [Pool] manages.
  ///
  /// If [reuse] is `true`, the pool can be used again after resources
  /// have been released. If not, the default, then the [allocate]
  /// and [using] methods must not be called after a call to `releaseAll`.
  void releaseAll({bool reuse = false}) {
    if (!reuse) {
      _inUse = false;
    }
    while (_managedResourceReleaseCallbacks.isNotEmpty) {
      _managedResourceReleaseCallbacks.removeLast()();
    }
    for (final p in _managedMemoryPointers) {
      _wrappedAllocator.free(p);
    }
    _managedMemoryPointers.clear();
  }

  /// Does nothing, invoke [releaseAll] instead.
  @override
  void free(Pointer<NativeType> pointer) {}

  void _ensureInUse() {
    if (!_inUse) {
      throw StateError(
          "Pool no longer in use, `releaseAll(reuse: false)` was called.");
    }
  }
}

/// Runs [computation] with a new [Pool], and releases all allocations at the end.
///
/// If [R] is a [Future], all allocations are released when the future completes.
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_
/// cleaned up.
R using<R>(R Function(Pool) computation,
    [Allocator wrappedAllocator = calloc]) {
  final pool = Pool(wrappedAllocator);
  bool isAsync = false;
  try {
    final result = computation(pool);
    if (result is Future) {
      isAsync = true;
      return (result.whenComplete(pool.releaseAll) as R);
    }
    return result;
  } finally {
    if (!isAsync) {
      pool.releaseAll();
    }
  }
}

/// Creates a zoned [Pool] to manage native resources.
///
/// The pool is availabe through [zonePool].
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
R withZonePool<R>(R Function() computation,
    [Allocator wrappedAllocator = calloc]) {
  final pool = Pool(wrappedAllocator);
  var poolHolder = [pool];
  bool isAsync = false;
  try {
    return runZoned(() {
      final result = computation();
      if (result is Future) {
        isAsync = true;
        result.whenComplete(pool.releaseAll);
      }
      return result;
    }, zoneValues: {#_pool: poolHolder});
  } finally {
    if (!isAsync) {
      pool.releaseAll();
      poolHolder.remove(pool);
    }
  }
}

/// A zone-specific [Pool].
///
/// Asynchronous computations can share a [Pool]. Use [withZonePool] to create
/// a new zone with a fresh [Pool], and that pool will then be released
/// automatically when the function passed to [withZonePool] completes.
/// All code inside that zone can use `zonePool` to access the pool.
///
/// The current pool must not be accessed by code which is not running inside
/// a zone created by [withZonePool].
Pool get zonePool {
  final List<Pool>? poolHolder = Zone.current[#_pool];
  if (poolHolder == null) {
    throw StateError("Not inside a zone created by `usePool`");
  }
  if (!poolHolder.isEmpty) {
    return poolHolder.single;
  }
  throw StateError("Pool as already been cleared with releaseAll.");
}
