// Copyright 2016 The Chromium 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:collection';

import 'package:meta/meta.dart';

/// Generates an [AppContext] value.
///
/// Generators are allowed to return `null`, in which case the context will
/// store the `null` value as the value for that type.
typedef Generator = dynamic Function();

/// An exception thrown by [AppContext] when you try to get a [Type] value from
/// the context, and the instantiation of the value results in a dependency
/// cycle.
class ContextDependencyCycleException implements Exception {
  ContextDependencyCycleException._(this.cycle);

  /// The dependency cycle (last item depends on first item).
  final List<Type> cycle;

  @override
  String toString() => 'Dependency cycle detected: ${cycle.join(' -> ')}';
}

/// The current [AppContext], as determined by the [Zone] hierarchy.
///
/// This will be the first context found as we scan up the zone hierarchy, or
/// the "root" context if a context cannot be found in the hierarchy. The root
/// context will not have any values associated with it.
///
/// This is guaranteed to never return `null`.
AppContext get context => Zone.current[_Key.key] ?? AppContext._root;

/// A lookup table (mapping types to values) and an implied scope, in which
/// code is run.
///
/// [AppContext] is used to define a singleton injection context for code that
/// is run within it. Each time you call [run], a child context (and a new
/// scope) is created.
///
/// Child contexts are created and run using zones. To read more about how
/// zones work, see https://www.dartlang.org/articles/libraries/zones.
class AppContext {
  AppContext._(
    this._parent,
    this.name, [
    this._overrides = const <Type, Generator>{},
    this._fallbacks = const <Type, Generator>{},
  ]);

  final String name;
  final AppContext _parent;
  final Map<Type, Generator> _overrides;
  final Map<Type, Generator> _fallbacks;
  final Map<Type, dynamic> _values = <Type, dynamic>{};

  List<Type> _reentrantChecks;

  /// Bootstrap context.
  static final AppContext _root = AppContext._(null, 'ROOT');

  dynamic _boxNull(dynamic value) => value ?? _BoxedNull.instance;

  dynamic _unboxNull(dynamic value) => value == _BoxedNull.instance ? null : value;

  /// Returns the generated value for [type] if such a generator exists.
  ///
  /// If [generators] does not contain a mapping for the specified [type], this
  /// returns `null`.
  ///
  /// If a generator existed and generated a `null` value, this will return a
  /// boxed value indicating null.
  ///
  /// If a value for [type] has already been generated by this context, the
  /// existing value will be returned, and the generator will not be invoked.
  ///
  /// If the generator ends up triggering a reentrant call, it signals a
  /// dependency cycle, and a [ContextDependencyCycleException] will be thrown.
  dynamic _generateIfNecessary(Type type, Map<Type, Generator> generators) {
    if (!generators.containsKey(type))
      return null;

    return _values.putIfAbsent(type, () {
      _reentrantChecks ??= <Type>[];

      final int index = _reentrantChecks.indexOf(type);
      if (index >= 0) {
        // We're already in the process of trying to generate this type.
        throw ContextDependencyCycleException._(
            UnmodifiableListView<Type>(_reentrantChecks.sublist(index)));
      }

      _reentrantChecks.add(type);
      try {
        return _boxNull(generators[type]());
      } finally {
        _reentrantChecks.removeLast();
        if (_reentrantChecks.isEmpty)
          _reentrantChecks = null;
      }
    });
  }

  /// Gets the value associated with the specified [type], or `null` if no
  /// such value has been associated.
  Object operator [](Type type) {
    dynamic value = _generateIfNecessary(type, _overrides);
    if (value == null && _parent != null)
      value = _parent[type];
    return _unboxNull(value ?? _generateIfNecessary(type, _fallbacks));
  }

  /// Runs [body] in a child context and returns the value returned by [body].
  ///
  /// If [overrides] is specified, the child context will return corresponding
  /// values when consulted via [operator[]].
  ///
  /// If [fallbacks] is specified, the child context will return corresponding
  /// values when consulted via [operator[]] only if its parent context didn't
  /// return such a value.
  ///
  /// If [name] is specified, the child context will be assigned the given
  /// name. This is useful for debugging purposes and is analogous to naming a
  /// thread in Java.
  Future<V> run<V>({
    @required FutureOr<V> body(),
    String name,
    Map<Type, Generator> overrides,
    Map<Type, Generator> fallbacks,
  }) async {
    final AppContext child = AppContext._(
      this,
      name,
      Map<Type, Generator>.unmodifiable(overrides ?? const <Type, Generator>{}),
      Map<Type, Generator>.unmodifiable(fallbacks ?? const <Type, Generator>{}),
    );
    return await runZoned<Future<V>>(
      () async => await body(),
      zoneValues: <_Key, AppContext>{_Key.key: child},
    );
  }

  @override
  String toString() {
    final StringBuffer buf = StringBuffer();
    String indent = '';
    AppContext ctx = this;
    while (ctx != null) {
      buf.write('AppContext');
      if (ctx.name != null)
        buf.write('[${ctx.name}]');
      if (ctx._overrides.isNotEmpty)
        buf.write('\n$indent  overrides: [${ctx._overrides.keys.join(', ')}]');
      if (ctx._fallbacks.isNotEmpty)
        buf.write('\n$indent  fallbacks: [${ctx._fallbacks.keys.join(', ')}]');
      if (ctx._parent != null)
        buf.write('\n$indent  parent: ');
      ctx = ctx._parent;
      indent += '  ';
    }
    return buf.toString();
  }
}

/// Private key used to store the [AppContext] in the [Zone].
class _Key {
  const _Key();

  static const _Key key = _Key();

  @override
  String toString() => 'context';
}

/// Private object that denotes a generated `null` value.
class _BoxedNull {
  const _BoxedNull();

  static const _BoxedNull instance = _BoxedNull();
}
