// Copyright (c) 2012, 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.

// ignore_for_file: deprecated_member_use_from_same_package

import 'package:test_api/hooks.dart' show pumpEventQueue;

import '../description.dart';
import '../interfaces.dart';
import '../util.dart';
import 'async_matcher.dart';
import 'expect.dart';
import 'throws_matcher.dart';
import 'util/pretty_print.dart';

/// Matches a [Future] that completes successfully with any value.
///
/// This creates an asynchronous expectation. The call to [expect] will return
/// immediately and execution will continue. To wait for the future to
/// complete and the expectation to run use [expectLater] and wait on the
/// returned future.
///
/// To test that a Future completes with an exception, you can use [throws] and
/// [throwsA].
final Matcher completes = const _Completes(null);

/// Matches a [Future] that completes successfully with a value that matches
/// [matcher].
///
/// This creates an asynchronous expectation. The call to [expect] will return
/// immediately and execution will continue. Later, when the future completes,
/// the expectation against [matcher] will run. To wait for the future to
/// complete and the expectation to run use [expectLater] and wait on the
/// returned future.
///
/// To test that a Future completes with an exception, you can use [throws] and
/// [throwsA].
Matcher completion(Object? matcher,
        [@Deprecated('this parameter is ignored') String? description]) =>
    _Completes(wrapMatcher(matcher));

class _Completes extends AsyncMatcher {
  final Matcher? _matcher;

  const _Completes(this._matcher);

  // Avoid async/await so we synchronously start listening to [item].
  @override
  dynamic /*FutureOr<String>*/ matchAsync(Object? item) {
    if (item is! Future) return 'was not a Future';

    return item.then((value) async {
      if (_matcher == null) return null;

      String? result;
      if (_matcher is AsyncMatcher) {
        result = await _matcher.matchAsync(value) as String?;
        if (result == null) return null;
      } else {
        var matchState = <Object?, Object?>{};
        if (_matcher.matches(value, matchState)) return null;
        result = _matcher
            .describeMismatch(value, StringDescription(), matchState, false)
            .toString();
      }

      var buffer = StringBuffer();
      buffer.writeln(indent(prettyPrint(value), first: 'emitted '));
      if (result.isNotEmpty) buffer.writeln(indent(result, first: '  which '));
      return buffer.toString().trimRight();
    });
  }

  @override
  Description describe(Description description) {
    if (_matcher == null) {
      description.add('completes successfully');
    } else {
      description.add('completes to a value that ').addDescriptionOf(_matcher);
    }
    return description;
  }
}

/// Matches a [Future] that does not complete.
///
/// Note that this creates an asynchronous expectation. The call to
/// `expect()` that includes this will return immediately and execution will
/// continue.
final Matcher doesNotComplete = const _DoesNotComplete();

class _DoesNotComplete extends Matcher {
  const _DoesNotComplete();

  @override
  Description describe(Description description) {
    description.add('does not complete');
    return description;
  }

  @override
  bool matches(Object? item, Map matchState) {
    if (item is! Future) return false;
    item.then((value) {
      fail('Future was not expected to complete but completed with a value of '
          '$value');
    });
    expect(pumpEventQueue(), completes);
    return true;
  }

  @override
  Description describeMismatch(
      Object? item, Description description, Map matchState, bool verbose) {
    if (item is! Future) return description.add('$item is not a Future');
    return description;
  }
}
