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

// @dart = 2.9

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

import 'package:ffi/ffi.dart';

import '../calloc.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.");
}
