// 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';

import '../calloc.dart';

/// Keeps track of all allocated memory and frees all allocated memory on
/// [releaseAll].
///
/// Wraps an [Allocator] to do the actual allocation and freeing.
class Pool implements Allocator {
  /// The [Allocator] used for allocation and freeing.
  final Allocator _wrappedAllocator;

  Pool(this._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 = [];

  /// Allocates memory on the native heap by using the allocator supplied to
  /// the constructor.
  ///
  /// Throws an [ArgumentError] if the number of bytes or alignment cannot be
  /// satisfied.
  @override
  Pointer<T> allocate<T extends NativeType>(int numBytes, {int? alignment}) {
    final p = _wrappedAllocator.allocate<T>(numBytes, alignment: alignment);
    _managedMemoryPointers.add(p);
    return p;
  }

  /// Registers [resource] in this pool.
  ///
  /// Executes [releaseCallback] on [releaseAll].
  T using<T>(T resource, Function(T) 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.
  void releaseAll() {
    for (final c in _managedResourceReleaseCallbacks) {
      c();
    }
    _managedResourceReleaseCallbacks.clear();
    for (final p in _managedMemoryPointers) {
      _wrappedAllocator.free(p);
    }
    _managedMemoryPointers.clear();
  }

  @override
  void free(Pointer<NativeType> pointer) => throw UnsupportedError(
      "Individually freeing Pool allocated memory is not allowed");
}

/// Creates a [Pool] to manage native resources.
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
R using<R>(R Function(Pool) f, [Allocator wrappedAllocator = calloc]) {
  final p = Pool(wrappedAllocator);
  try {
    return f(p);
  } finally {
    p.releaseAll();
  }
}

/// Creates a zoned [Pool] to manage native resources.
///
/// Pool is availabe through [currentPool].
///
/// Please note that all throws are caught and packaged in [RethrownError].
///
/// If the isolate is shut down, through `Isolate.kill()`, resources are _not_ cleaned up.
R usePool<R>(R Function() f, [Allocator wrappedAllocator = calloc]) {
  final p = Pool(wrappedAllocator);
  try {
    return runZoned(() => f(),
        zoneValues: {#_pool: p},
        onError: (error, st) => throw RethrownError(error, st));
  } finally {
    p.releaseAll();
  }
}

/// The [Pool] in the current zone.
Pool get currentPool => Zone.current[#_pool];

class RethrownError {
  dynamic original;
  StackTrace originalStackTrace;
  RethrownError(this.original, this.originalStackTrace);
  toString() => """RethrownError(${original})
${originalStackTrace}""";
}
