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

// TODO Add doc about how failure strings work.
import 'dart:async';

import 'package:test_api/hooks.dart';

import 'describe.dart';

/// A target for checking expectations against a value in a test.
///
/// A Check my have a real value, in which case the expectations can be
/// validated or rejected; or it may be a placeholder, in which case
/// expectations describe what would be checked but cannot be rejected.
///
/// Expectations are defined as extension methods specialized on the generic
/// [T]. Expectations can use the [ContextExtension] to interact with the
/// [Context] for this check.
class Check<T> {
  final Context<T> _context;
  Check._(this._context);

  /// Mark the currently running test as skipped and return a [Check] that will
  /// ignore all expectations.
  ///
  /// Any expectations against the return value will not be checked and will not
  /// be included in the "Expected" or "Actual" string representations of a
  /// failure.
  ///
  /// ```dart
  /// checkThat(actual)
  ///     ..stillChecked()
  ///     ..skip('reason the expectation is temporarily not met').notChecked();
  /// ```
  ///
  /// If `skip` is used in a callback passed to `softCheck` or `describe` it
  /// will still mark the test as skipped, even though failing the expectation
  /// would not have otherwise caused the test to fail.
  Check<T> skip(String message) {
    TestHandle.current.markSkipped(message);
    return Check._(_SkippedContext());
  }
}

/// Creates a [Check] that can be used to validate expectations against [value].
///
/// Expectations that are not satisfied throw a [TestFailure] to interrupt the
/// currently running test and mark it as failed.
///
/// If [because] is passed it will be included as a "Reason:" line in failure
/// messages.
///
/// ```dart
/// checkThat(actual).equals(expected);
/// ```
Check<T> checkThat<T>(T value, {String? because}) => Check._(_TestContext._(
    value: _Present(value),
    // TODO - switch between "a" and "an"
    label: 'a $T',
    reason: because,
    fail: (m, _) => throw TestFailure(m),
    allowAsync: true));

/// Checks whether [value] satisfies all expectations invoked in [condition].
///
/// Returns `null` if all expectations are satisfied, otherwise returns the
/// [Rejection] for the first expectation that fails.
///
/// Asynchronous expectations are not allowed in [condition] and will cause a
/// runtime error if they are used.
Rejection? softCheck<T>(T value, void Function(Check<T>) condition) {
  Rejection? rejection;
  final check = Check<T>._(_TestContext._(
      value: _Present(value),
      fail: (_, r) {
        rejection = r;
      },
      allowAsync: false));
  condition(check);
  return rejection;
}

/// Creates a description of the expectations checked by [condition].
///
/// The strings are individual lines of a description.
/// The description of an expectation may be one or more adjacent lines.
///
/// Matches the "Expected: " lines in the output of a failure message if a value
/// did not meet the last expectation in [condition], without the first labeled
/// line.
Iterable<String> describe<T>(void Function(Check<T>) condition) {
  final context = _TestContext<T>._(
      value: _Absent(),
      fail: (_, __) {
        throw UnimplementedError();
      },
      allowAsync: false);
  condition(Check._(context));
  return context.expected.skip(1);
}

extension ContextExtension<T> on Check<T> {
  /// The expectations and nesting context for this check.
  Context<T> get context => _context;
}

/// The expectation and nesting context already applied to a [Check].
///
/// This is the surface of interaction for expectation extension method
/// implementations.
///
/// The `expect` and `expectAsync` can test the value and optionally reject it.
/// The `nest` and `nestAsync` can test the value, and also extract some other
/// property from it for further checking.
abstract class Context<T> {
  /// Expect that [predicate] will not return a [Rejection] for the checked
  /// value.
  ///
  /// The property that is asserted by this expectation is described by
  /// [clause]. Often this is a single statement like "equals <1>" or "is
  /// greater than 10", but it may be multiple lines such as describing that an
  /// Iterable contains an element meeting a complex expectation. If any element
  /// in the returned iterable contains a newline it may cause problems with
  /// indentation in the output.
  void expect(
      Iterable<String> Function() clause, Rejection? Function(T) predicate);

  /// Expect that [predicate] will not result in a [Rejection] for the checked
  /// value.
  ///
  /// The property that is asserted by this expectation is described by
  /// [clause]. Often this is a single statement like "equals <1>" or "is
  /// greater than 10", but it may be multiple lines such as describing that an
  /// Iterable contains an element meeting a complex expectation. If any element
  /// in the returned iterable contains a newline it may cause problems with
  /// indentation in the output.
  ///
  /// Some context may disallow asynchronous expectations, for instance in
  /// [softCheck] which must synchronously check the value. In those contexts
  /// this method will throw.
  Future<void> expectAsync<R>(Iterable<String> Function() clause,
      FutureOr<Rejection?> Function(T) predicate);

  /// Extract a property from the value for further checking.
  ///
  /// If the property cannot be extracted, [extract] should return an
  /// [Extracted.rejection] describing the problem. Otherwise it should return
  /// an [Extracted.value].
  ///
  /// The [label] will be used preceding "that:" in a description. Expectations
  /// applied to the returned [Check] will follow the label, indented by two
  /// more spaces.
  ///
  /// If [atSameLevel] is true then [R] should be a subtype of [T], and a
  /// returned [Extracted.value] should be the same instance as passed value.
  /// This may be useful to refine the type for further checks. In this case the
  /// label is used like a single line "clause" passed to [expect], and
  /// expectations applied to the return [Check] will behave as if they were
  /// applied to the Check for this context.
  Check<R> nest<R>(String label, Extracted<R> Function(T) extract,
      {bool atSameLevel = false});

  /// Extract an asynchronous property from the value for further checking.
  ///
  /// If the property cannot be extracted, [extract] should return an
  /// [Extracted.rejection] describing the problem. Otherwise it should return
  /// an [Extracted.value].
  ///
  /// The [label] will be used preceding "that:" in a description. Expectations
  /// applied to the returned [Check] will follow the label, indented by two
  /// more spaces.
  ///
  /// Some context may disallow asynchronous expectations, for instance in
  /// [softCheck] which must synchronously check the value. In those contexts
  /// this method will throw.
  Future<Check<R>> nestAsync<R>(
      String label, FutureOr<Extracted<R>> Function(T) extract);
}

/// A property extracted from a value being checked, or a rejection.
class Extracted<T> {
  final Rejection? rejection;
  final T? value;
  Extracted.rejection({required String actual, Iterable<String>? which})
      : this.rejection = Rejection(actual: actual, which: which),
        this.value = null;
  Extracted.value(this.value) : this.rejection = null;

  Extracted._(this.rejection) : this.value = null;

  Extracted<R> _map<R>(R Function(T) transform) {
    if (rejection != null) return Extracted._(rejection);
    return Extracted.value(transform(value as T));
  }
}

abstract class _Optional<T> {
  R? apply<R extends FutureOr<Rejection?>>(R Function(T) callback);
  Future<Extracted<_Optional<R>>> mapAsync<R>(
      FutureOr<Extracted<R>> Function(T) transform);
  Extracted<_Optional<R>> map<R>(Extracted<R> Function(T) transform);
}

class _Present<T> implements _Optional<T> {
  final T value;
  _Present(this.value);

  @override
  R? apply<R extends FutureOr<Rejection?>>(R Function(T) c) => c(value);

  @override
  Future<Extracted<_Present<R>>> mapAsync<R>(
      FutureOr<Extracted<R>> Function(T) transform) async {
    final transformed = await transform(value);
    return transformed._map((v) => _Present(v));
  }

  @override
  Extracted<_Present<R>> map<R>(Extracted<R> Function(T) transform) =>
      transform(value)._map((v) => _Present(v));
}

class _Absent<T> implements _Optional<T> {
  @override
  R? apply<R extends FutureOr<Rejection?>>(R Function(T) c) => null;

  @override
  Future<Extracted<_Absent<R>>> mapAsync<R>(
          FutureOr<Extracted<R>> Function(T) transform) async =>
      Extracted.value(_Absent<R>());

  @override
  Extracted<_Absent<R>> map<R>(FutureOr<Extracted<R>> Function(T) transform) =>
      Extracted.value(_Absent<R>());
}

class _TestContext<T> implements Context<T>, _ClauseDescription {
  final _Optional<T> _value;
  final _TestContext<dynamic>? _parent;

  final List<_ClauseDescription> _clauses;
  final List<_TestContext> _aliases;

  // The "a value" in "a value that:".
  final String _label;
  final String? _reason;

  final void Function(String, Rejection?) _fail;

  final bool _allowAsync;

  _TestContext._({
    required _Optional<T> value,
    required void Function(String, Rejection?) fail,
    required bool allowAsync,
    String? label,
    String? reason,
  })  : _value = value,
        _label = label ?? '',
        _reason = reason,
        _fail = fail,
        _allowAsync = allowAsync,
        _parent = null,
        _clauses = [],
        _aliases = [];

  _TestContext._alias(_TestContext original, this._value)
      : _parent = original._parent,
        _clauses = original._clauses,
        _aliases = original._aliases,
        _fail = original._fail,
        _allowAsync = original._allowAsync,
        // Properties that are never read from an aliased context
        _label = '',
        _reason = null;

  _TestContext._child(this._value, this._label, _TestContext<dynamic> parent)
      : _parent = parent,
        _fail = parent._fail,
        _allowAsync = parent._allowAsync,
        _clauses = [],
        _aliases = [],
        // Properties that are never read from any context other than root
        _reason = null;

  @override
  void expect(
      Iterable<String> Function() clause, Rejection? Function(T) predicate) {
    _clauses.add(_StringClause(clause));
    final rejection = _value.apply(predicate);
    if (rejection != null) {
      _fail(_failure(rejection), rejection);
    }
  }

  @override
  Future<void> expectAsync<R>(Iterable<String> Function() clause,
      FutureOr<Rejection?> Function(T) predicate) async {
    if (!_allowAsync) {
      throw StateError(
          'Async expectations cannot be used in a synchronous check');
    }
    _clauses.add(_StringClause(clause));
    final outstandingWork = TestHandle.current.markPending();
    final rejection = await _value.apply(predicate);
    outstandingWork.complete();
    if (rejection == null) return;
    _fail(_failure(rejection), rejection);
  }

  String _failure(Rejection rejection) {
    final root = _root;
    return [
      ..._prefixFirst('Expected: ', root.expected),
      ..._prefixFirst('Actual: ', root.actual(rejection, this)),
      if (_reason != null) 'Reason: $_reason',
    ].join('\n');
  }

  @override
  Check<R> nest<R>(String label, Extracted<R> Function(T) extract,
      {bool atSameLevel = false}) {
    final result = _value.map(extract);
    final rejection = result.rejection;
    if (rejection != null) {
      _clauses.add(_StringClause(() => [label]));
      _fail(_failure(rejection), rejection);
    }
    final value = result.value ?? _Absent<R>();
    final _TestContext<R> context;
    if (atSameLevel) {
      context = _TestContext._alias(this, value);
      _aliases.add(context);
      _clauses.add(_StringClause(() => [label]));
    } else {
      context = _TestContext._child(value, label, this);
      _clauses.add(context);
    }
    return Check._(context);
  }

  @override
  Future<Check<R>> nestAsync<R>(
      String label, FutureOr<Extracted<R>> Function(T) extract) async {
    if (!_allowAsync) {
      throw StateError(
          'Async expectations cannot be used in a synchronous check');
    }
    final outstandingWork = TestHandle.current.markPending();
    final result = await _value.mapAsync(extract);
    outstandingWork.complete();
    final rejection = result.rejection;
    if (rejection != null) {
      _clauses.add(_StringClause(() => [label]));
      _fail(_failure(rejection), rejection);
    }
    // TODO - does this need null fallback instead?
    final value = result.value as _Optional<R>;
    final context = _TestContext<R>._child(value, label, this);
    _clauses.add(context);
    return Check._(context);
  }

  _TestContext get _root {
    _TestContext<dynamic> current = this;
    while (current._parent != null) {
      current = current._parent!;
    }
    return current;
  }

  @override
  Iterable<String> get expected {
    assert(_clauses.isNotEmpty);
    return [
      '$_label that:',
      for (var clause in _clauses) ...indent(clause.expected),
    ];
  }

  @override
  Iterable<String> actual(Rejection rejection, Context<dynamic> failedContext) {
    if (identical(failedContext, this) || _aliases.contains(failedContext)) {
      final which = rejection.which;
      return [
        if (_parent != null) '$_label that:',
        '${_parent != null ? 'Actual: ' : ''}${rejection.actual}',
        if (which != null && which.isNotEmpty) ..._prefixFirst('Which: ', which)
      ];
    } else {
      return [
        '$_label that:',
        for (var clause in _clauses)
          ...indent(clause.actual(rejection, failedContext))
      ];
    }
  }
}

class _SkippedContext<T> implements Context<T> {
  @override
  void expect(
      Iterable<String> Function() clause, Rejection? Function(T) predicate) {
    // Ignore
  }

  @override
  Future<void> expectAsync<R>(Iterable<String> Function() clause,
      FutureOr<Rejection?> Function(T) predicate) async {
    // Ignore
  }

  @override
  Check<R> nest<R>(String label, Extracted<R> Function(T p1) extract,
      {bool atSameLevel = false}) {
    return Check._(_SkippedContext());
  }

  @override
  Future<Check<R>> nestAsync<R>(
      String label, FutureOr<Extracted<R>> Function(T p1) extract) async {
    return Check._(_SkippedContext());
  }
}

abstract class _ClauseDescription {
  Iterable<String> get expected;
  Iterable<String> actual(Rejection rejection, Context<dynamic> context);
}

class _StringClause implements _ClauseDescription {
  final Iterable<String> Function() _expected;
  @override
  Iterable<String> get expected => _expected();
  _StringClause(this._expected);
  // Assumes this will never get called when it was this clause that failed
  // because the TestContext that fails never inspect it's clauses and just
  // prints the failed one.
  // TODO: better way to model this?
  @override
  Iterable<String> actual(Rejection rejection, Context<dynamic> context) =>
      expected;
}

/// A description of a value that failed an expectation.
class Rejection {
  /// A description of the actual value as it relates to the expectation.
  ///
  /// This may use [literal] to show a String representation of the value, or it
  /// may be a description of a specific aspect of the value. For instance an
  /// expectation that a Future completes to a value may describe the actual as
  /// "A Future that completes to an error".
  ///
  /// This is printed following an "Actual: " label in the output of a failure
  /// message. The message will be indented to the level of the expectation in
  /// the description, and printed following the descriptions of any
  /// expectations that have already passed.
  final String actual;

  /// A description of the way that [actual] failed to meet the expectation.
  ///
  /// An expectation can provide extra detail, or focus attention on a specific
  /// part of the value. For instance when comparing multiple elements in a
  /// collection, the rejection may describe that the value "has an unequal
  /// value at index 3".
  ///
  /// Lines should be separate values in the iterable, if any element contains a
  /// newline it may cause problems with indentation in the output.
  ///
  /// When provided, this is printed following a "Which: " label at the end of
  /// the output for the failure message.
  final Iterable<String>? which;

  Rejection({required this.actual, this.which});
}

Iterable<String> _prefixFirst(String prefix, Iterable<String> lines) sync* {
  var isFirst = true;
  for (var line in lines) {
    if (isFirst) {
      yield '$prefix$line';
      isFirst = false;
    } else {
      yield line;
    }
  }
}
