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

part of Expect;

/// Expect is used for tests that do not want to make use of the
/// Dart unit test library - for example, the core language tests.
/// Third parties are discouraged from using this, and should use
/// the expect() function in the unit test library instead for
/// test assertions.
///
/// This part contains all except
///   static void _fail(String message) {}

class Expect {
  /**
   * Checks whether the expected and actual values are equal (using `==`).
   */
  static void equals(var expected, var actual, [String? reason = null]) {
    if (expected == actual) return;
    if ((expected is double) &&
        (actual is double) &&
        (expected.isNaN) &&
        (actual.isNaN)) {
      return;
    }
    String msg = _getMessage(reason);
    _fail("Expect.equals(expected: <$expected>, actual: <$actual>$msg) fails.");
  }

  /**
   * Checks whether the actual value is a bool and its value is true.
   */
  static void isTrue(var actual, [String? reason = null]) {
    if (_identical(actual, true)) return;
    String msg = _getMessage(reason);
    _fail("Expect.isTrue($actual$msg) fails.");
  }

  /**
   * Checks whether the actual value is a bool and its value is false.
   */
  static void isFalse(var actual, [String? reason = null]) {
    if (_identical(actual, false)) return;
    String msg = _getMessage(reason);
    _fail("Expect.isFalse($actual$msg) fails.");
  }

  /**
   * Checks whether [actual] is null.
   */
  static void isNull(actual, [String? reason = null]) {
    if (null == actual) return;
    String msg = _getMessage(reason);
    _fail("Expect.isNull(actual: <$actual>$msg) fails.");
  }

  /**
   * Checks whether [actual] is not null.
   */
  static void isNotNull(actual, [String? reason = null]) {
    if (null != actual) return;
    String msg = _getMessage(reason);
    _fail("Expect.isNotNull(actual: <$actual>$msg) fails.");
  }

  /**
   * Checks whether the expected and actual values are identical
   * (using `identical`).
   */
  static void identical(var expected, var actual, [String? reason = null]) {
    if (_identical(expected, actual)) return;
    String msg = _getMessage(reason);
    _fail("Expect.identical(expected: <$expected>, actual: <$actual>$msg) "
        "fails.");
  }

  // Unconditional failure.
  static void fail(String? msg) {
    _fail("Expect.fail('$msg')");
  }

  /**
   * Failure if the difference between expected and actual is greater than the
   * given tolerance. If no tolerance is given, tolerance is assumed to be the
   * value 4 significant digits smaller than the value given for expected.
   */
  static void approxEquals(num expected, num actual,
      [num? tolerance = null, String? reason = null]) {
    if (tolerance == null) {
      tolerance = (expected / 1e4).abs();
    }
    // Note: use !( <= ) rather than > so we fail on NaNs
    if ((expected - actual).abs() <= tolerance) return;

    String msg = _getMessage(reason);
    _fail('Expect.approxEquals(expected:<$expected>, actual:<$actual>, '
        'tolerance:<$tolerance>$msg) fails');
  }

  static void notEquals(unexpected, actual, [String? reason = null]) {
    if (unexpected != actual) return;
    String msg = _getMessage(reason);
    _fail("Expect.notEquals(unexpected: <$unexpected>, actual:<$actual>$msg) "
        "fails.");
  }

  /**
   * Specialized equality test for strings. When the strings don't match,
   * this method shows where the mismatch starts and ends.
   */
  static void stringEquals(String? expected, String? actual,
      [String? reason = null]) {
    String msg = _getMessage(reason);
    String defaultMessage =
        'Expect.stringEquals(expected: <$expected>", <$actual>$msg) fails';

    if (expected == actual) return;
    if ((expected == null) || (actual == null)) {
      _fail('$defaultMessage');
      return;
    }
    // scan from the left until we find a mismatch
    int left = 0;
    int eLen = expected.length;
    int aLen = actual.length;
    while (true) {
      if (left == eLen) {
        assert(left < aLen);
        String snippet = actual.substring(left, aLen);
        _fail('$defaultMessage\nDiff:\n...[  ]\n...[ $snippet ]');
        return;
      }
      if (left == aLen) {
        assert(left < eLen);
        String snippet = expected.substring(left, eLen);
        _fail('$defaultMessage\nDiff:\n...[  ]\n...[ $snippet ]');
        return;
      }
      if (expected[left] != actual[left]) {
        break;
      }
      left++;
    }

    // scan from the right until we find a mismatch
    int right = 0;
    while (true) {
      if (right == eLen) {
        assert(right < aLen);
        String snippet = actual.substring(0, aLen - right);
        _fail('$defaultMessage\nDiff:\n[  ]...\n[ $snippet ]...');
        return;
      }
      if (right == aLen) {
        assert(right < eLen);
        String snippet = expected.substring(0, eLen - right);
        _fail('$defaultMessage\nDiff:\n[  ]...\n[ $snippet ]...');
        return;
      }
      // stop scanning if we've reached the end of the left-to-right match
      if (eLen - right <= left || aLen - right <= left) {
        break;
      }
      if (expected[eLen - right - 1] != actual[aLen - right - 1]) {
        break;
      }
      right++;
    }
    String eSnippet = expected.substring(left, eLen - right);
    String aSnippet = actual.substring(left, aLen - right);
    String diff = '\nDiff:\n...[ $eSnippet ]...\n...[ $aSnippet ]...';
    _fail('$defaultMessage$diff');
  }

  /**
   * Checks that every element of [expected] is also in [actual], and that
   * every element of [actual] is also in [expected].
   */
  static void setEquals(Iterable<Object?> expected, Iterable<Object?> actual,
      [String? reason = null]) {
    final missingSet = new Set.from(expected);
    missingSet.removeAll(actual);
    final extraSet = new Set.from(actual);
    extraSet.removeAll(expected);

    if (extraSet.isEmpty && missingSet.isEmpty) return;
    String msg = _getMessage(reason);

    StringBuffer sb = new StringBuffer("Expect.setEquals($msg) fails");
    // Report any missing items.
    if (!missingSet.isEmpty) {
      sb.write('\nExpected collection does not contain: ');
    }

    for (final val in missingSet) {
      sb.write('$val ');
    }

    // Report any extra items.
    if (!extraSet.isEmpty) {
      sb.write('\nExpected collection should not contain: ');
    }

    for (final val in extraSet) {
      sb.write('$val ');
    }
    _fail(sb.toString());
  }

  /**
   * Calls the function [f] and verifies that it throws an exception.
   * The optional [check] function can provide additional validation
   * that the correct exception is being thrown.  For example, to check
   * the type of the exception you could write this:
   *
   *     Expect.throws(myThrowingFunction, (e) => e is MyException);
   */
  static void throws(void f(),
      [_CheckExceptionFn? check = null, String? reason = null]) {
    try {
      f();
    } catch (e, s) {
      if (check != null) {
        if (!check(e)) {
          String msg = reason == null ? "" : reason;
          _fail("Expect.throws($msg): Unexpected ${e.runtimeType}('$e')\n$s");
        }
      }
      return;
    }
    String msg = reason == null ? "" : reason;
    _fail('Expect.throws($msg) fails');
  }

  static String _getMessage(String? reason) =>
      (reason == null) ? "" : ", '$reason'";

  static void listEquals(var expected, var actual, [String? reason = null]) {
    if (expected is! List) {
      Expect.fail("expected is not a List:$expected");
    }
    if (actual is! List) {
      Expect.fail("actual is not a List:$expected");
    }
    deepEquals(expected, actual, reason);
  }

  static void mapEquals(var expected, var actual, [String? reason = null]) {
    if ((expected is! Map) || (actual is! Map)) {
      Expect.fail("not a Map");
    }
    deepEquals(expected, actual, reason);
  }

  /** checks that both collections have identical topology and equal primitive elements.
   *  useful to check cyclic collections passed through ports and streams.
   */
  static void deepEquals(var expected, var actual, [String? reason = null]) {
    Map planned = new Map();
    Map processed = new Map();

    void plan2check(var expected, var actual) {
      if (expected == null) {
        Expect.isNull(actual);
      }
      ;
      if ((expected is Map) || (expected is List)) {
        var savedActual = planned[expected];
        if (savedActual != null) {
          // this pair is planned to investigate
          Expect.equals(savedActual, actual);
        } else if ((savedActual = processed[expected]) != null) {
          // this pair is checked already
          Expect.equals(savedActual, actual);
        } else {
          // this pair is not yet investigated
          Expect.equals(expected.length, actual.length,
              "Collections' lengths are not equal: expected length=${expected.length}, actual length=${actual.length}");
          planned[expected] = actual;
        }
      } else {
        Expect.equals(expected, actual);
      }
    }

    void runPlanned(var expected, var actual) {
      if (expected is Map) {
        for (var key in expected.keys) {
//        TODO check that key sets are equivalent. Following method does not work:
//          Expect.isTrue(actual.keys.toSet().remove(key)");
          plan2check(expected[key], actual[key]);
        }
      } else if (expected is List) {
        for (int i = 0; i != expected.length; i++) {
          plan2check(expected[i], actual[i]);
        }
      } else {
        Expect.fail("only Lists and Maps expected in the plan");
      }
      // move pair from planned to processed
      planned.remove(expected);
      processed[expected] = actual;
    }

    try {
      plan2check(expected, actual);
      for (;;) {
        Iterable keys = planned.keys;
        if (keys.isEmpty) {
          return;
        }
        var key = keys.first;
        runPlanned(key, planned[key]);
      }
    } catch (error) {
      String msg = _getMessage(reason);
      _fail('deepEquals($expected, $actual, $msg) fails\n   [cause: $error]');
    }
  }

  static void iterableEquals(Iterable expected, Iterable actual) {
    Iterator eit = expected.iterator;
    Iterator ait = actual.iterator;
    while (eit.moveNext()) {
      Expect.isTrue(ait.moveNext());
      Expect.equals(eit.current, ait.current);
    }
    Expect.isFalse(ait.moveNext());
  }
}

bool _identical(a, b) => identical(a, b);

typedef bool _CheckExceptionFn(exception);

class ExpectException implements Exception {
  String? message;
  ExpectException([this.message]);
  String toString() => message ?? "";
}

/// Is true iff `assert` statements are enabled.
final bool assertStatementsEnabled = (() {
  bool result = false;
  assert(result = true);
  return result;
})();

/// Is true iff js compiler is used
final bool isJS = identical(1.0, 1);
