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

import "dart:async" show FutureOr;
import "package:expect/expect.dart";
import "package:expect/static_type_helper.dart";
// All extensions are exported by `dart:core`.

void main() {
  // Null-related extensions.
  testNonNulls();
  testFirstOrNull();
  testLastOrNull();
  testSingleOrNull();
  testElementAtOrNull();

  // Record-related extensions.
  testIndexed();
}

void testNonNulls() {
  // Static behavior.
  {
    // Removes nullability from element type.
    Iterable<int?> target = [];
    var result = target.nonNulls;
    result.expectStaticType<Exactly<Iterable<int>>>();
  }
  {
    // Works on subtypes of iterable.
    List<int?> target = [];
    var result = target.nonNulls;
    result.expectStaticType<Exactly<Iterable<int>>>();
  }
  {
    // Works on non-nullable types too (wish it didn't).
    Iterable<int> target = [];
    var result = target.nonNulls;
    result.expectStaticType<Exactly<Iterable<int>>>();
  }
  {
    // Removes nullability from `Never?`, giving `Never`.
    // (Cannot remove nullability from `Null`, so doesn't match
    // `Iterable<Null>`.)
    Iterable<Never?> target = [];
    var result = target.nonNulls;
    result.expectStaticType<Exactly<Iterable<Never>>>();
  }

  // Dynamic behavior.

  void test<T extends Object>(
    String name,
    Iterable<T?> input,
    List<T> expectedResults,
  ) {
    var actualResults = input.nonNulls;
    Expect.type<Iterable<T>>(actualResults, "$name type");
    Expect.listEquals(expectedResults, [...actualResults], "$name result");
  }

  test<int>("empty iterable", Iterable.empty(), []);
  test<int>("empty list", [], []);
  test<int>("all non-null", numbers(5), [1, 2, 3, 4, 5]);
  test<int>("all null", numbers(5, where: none), []);
  test<int>("one non-null", numbers(5, where: only(3)), [3]);
  test<int>("some null", numbers(5, where: even), [2, 4]);
  test<int>("some null, list", [null, 2, null, 4, null], [2, 4]);

  // Is lazy.
  var nonNulls = numbers(5, where: even, throwAt: 3).nonNulls;
  var it = nonNulls.iterator;
  Expect.isTrue(it.moveNext());
  Expect.equals(2, it.current);
  Expect.throws<UnimplementedError>(it.moveNext);
}

void testFirstOrNull() {
  // Static behavior.
  // (Tested to ensure extension captures the correct type,
  // and the correct extension member is applied).
  {
    Iterable<int> target = [];
    var result = target.firstOrNull;
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<int?> target = [];
    var result = target.firstOrNull;
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<Never> target = [];
    var result = target.firstOrNull;
    result.expectStaticType<Exactly<Null>>();
  }
  // Dynamic behavior.
  void test<T extends Object>(
    String name,
    Iterable<T?> source,
    T? expectedResult,
  ) {
    var actualResult = source.firstOrNull;
    Expect.equals(expectedResult, actualResult, "firstOrNull $name");
  }

  test<int>("Empty iterable", Iterable.empty(), null);
  test<Never>("Empty iterable", Iterable.empty(), null);
  test<int>("Empty list", [], null);
  test<int>("Single value", numbers(1), 1);
  test<int>("Multiple values", numbers(3), 1);
  test<int>("Nullable values", numbers(3, where: even), null);
  test<int>("Stops after first", numbers(3, throwAt: 2), 1);
  Expect.throws<UnimplementedError>(
    () => numbers(3, throwAt: 1).firstOrNull,
    null,
    "firstOrNull first throws",
  );
}

void testLastOrNull() {
  // Static behavior.
  {
    Iterable<int> target = [];
    var result = target.lastOrNull;
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<int?> target = [];
    var result = target.lastOrNull;
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<Never> target = [];
    var result = target.lastOrNull;
    result.expectStaticType<Exactly<Null>>();
  }
  // Dynamic behavior.
  void test<T>(String name, Iterable<T> source, T? expectedResult) {
    var actualResult = source.lastOrNull;
    Expect.equals(expectedResult, actualResult, "lastOrNull $name");
  }

  test<int>("Empty iterable", Iterable.empty(), null);
  test<Never>("Empty iterable", Iterable.empty(), null);
  test<int>("Empty list", [], null);
  test<int?>("Single value", numbers(1), 1);
  test<int?>("Multiple values", numbers(3), 3);
  test<int?>("Nullable values", numbers(3, where: even), null);
  Expect.throws<UnimplementedError>(
    () => numbers(3, throwAt: 1).lastOrNull,
    null,
    "lastOrNull first throws",
  );
  Expect.throws<UnimplementedError>(
    () => numbers(3, throwAt: 3).lastOrNull,
    null,
    "lastOrNull last throws",
  );
  Expect.throws<UnimplementedError>(
    () => CurrentThrowIterable<int?>(numbers(3), 2).lastOrNull,
    null,
    "lastOrNull throw on current",
  );
}

void testSingleOrNull() {
  // Static behavior.
  {
    Iterable<int> target = [];
    var result = target.singleOrNull;
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<int?> target = [];
    var result = target.singleOrNull;
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<Never> target = [];
    var result = target.singleOrNull;
    result.expectStaticType<Exactly<Null>>();
  }
  // Dynamic behavior.
  void test<T>(String name, Iterable<T> source, T? expectedResult) {
    var actualResult = source.singleOrNull;
    Expect.equals(expectedResult, actualResult, "singleOrNull $name");
  }

  test<int>("Empty iterable", Iterable.empty(), null);
  test<Never>("Empty iterable", Iterable.empty(), null);
  test<int>("Empty list", [], null);
  test<int?>("Single value", numbers(1), 1);
  test<int?>("Multiple values", numbers(3), null);
  test<int?>("Nullable values", numbers(3, where: even), null);
  Expect.throws<UnimplementedError>(
    () => numbers(3, throwAt: 1).singleOrNull,
    null,
    "singleOrNull first throws",
  );
  Expect.throws<UnimplementedError>(
    () => numbers(3, throwAt: 2).singleOrNull,
    null,
    "singleOrNull second throws",
  );
  test<int?>("Throws after two", numbers(3, throwAt: 3), null);
}

void testElementAtOrNull() {
  // Static behavior.
  {
    Iterable<int> target = [];
    var result = target.elementAtOrNull(0);
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<int?> target = [];
    var result = target.elementAtOrNull(0);
    result.expectStaticType<Exactly<int?>>();
  }
  {
    Iterable<Never> target = [];
    var result = target.elementAtOrNull(0);
    result.expectStaticType<Exactly<Null>>();
  }
  // Dynamic behavior.
  void test<T>(String name, Iterable<T> source, int index, T? expectedResult) {
    var actualResult = source.elementAtOrNull(index);
    Expect.equals(
      expectedResult,
      actualResult,
      "elementAtOrNull($index) $name",
    );
  }

  Expect.throwsArgumentError(
    () => numbers(3).elementAtOrNull(-1),
    "elementAtOrNull(negative) first throws",
  );

  test<int>("Empty iterable", Iterable<int>.empty(), 0, null);
  test<int>("Empty iterable", Iterable<int>.empty(), 1000000, null);
  test<Never>("Empty iterable", Iterable<Never>.empty(), 0, null);
  test<int>("Empty list", [], 0, null);
  test<int?>("Single value", numbers(1), 0, 1);
  test<int?>("Single value", numbers(1), 1, null);
  test<int?>("Multiple values first", numbers(3), 0, 1);
  test<int?>("Multiple values mid", numbers(3), 1, 2);
  test<int?>("Multiple values last", numbers(3), 2, 3);
  test<int?>("Multiple values overshoot", numbers(3), 3, null);
  test<int?>("Nullable values found", numbers(3, where: even), 2, null);
  test<int?>("Nullable values not found", numbers(3, where: even), 3, null);
  Expect.throws<UnimplementedError>(
    () => numbers(3, throwAt: 1).elementAtOrNull(1),
    null,
    "elementAtOrNull(1) first throws",
  );
  Expect.throws<UnimplementedError>(
    () => numbers(3, throwAt: 2).elementAtOrNull(2),
    null,
    "elementAtOrNull(2) second throws",
  );
  test<int?>("Throws after two", numbers(3, throwAt: 3), 1, 2);

  var currentThrow2 = CurrentThrowIterable<int?>(numbers(3), 2);
  test<int?>("Throws current middle", currentThrow2, 0, 1);
  test<int?>("Throws current middle", currentThrow2, 2, 3);
  Expect.throws<UnimplementedError>(() => currentThrow2.elementAt(1));
}

void testIndexed() {
  void test<T>(String name, Iterable<T> elements) {
    var values = elements.toList();
    var indexed = elements.indexed;
    testRec(name, values, indexed, 0, false);
  }

  // Non-efficient-length iterables.
  test<int?>("NELI empty", numbers(0));
  test<int?>("NELI single", numbers(1));
  test<int?>("NELI two", numbers(2));
  test<int?>("NELI more", numbers(10));

  // Efficient-length iterables (a list's `map` has efficient length).
  test<int?>("ELI empty", numbers(0).toList().map((x) => x));
  test<int?>("ELI single", numbers(1).toList().map((x) => x));
  test<int?>("ELI two", numbers(2).toList().map((x) => x));
  test<int?>("ELI more", numbers(10).toList().map((x) => x));
}

// Helper function for `testIndexed`. Top-level because dart2js crashes
// on recursive generic local functions.
//
// If [rec] is true, we're doing a recursive test on skip/take/both,
// and `start` the number of leading elements skipped.
void testRec<T>(
  String name,
  List<T> values,
  Iterable<(int, T)> indexed,
  int start,
  bool rec,
) {
  var length = values.length;
  Expect.equals(length, indexed.length, "$values length");
  Expect.equals(values.isEmpty, indexed.isEmpty);
  Expect.equals(values.isNotEmpty, indexed.isNotEmpty);
  Expect.listEquals([
    for (var i = 0; i < length; i++) (start + i, values[i]),
  ], indexed.toList());

  int index = 0;
  indexed.forEach((pair) {
    Expect.equals(start + index, pair.$1);
    Expect.equals(values[index], pair.$2);
    index++;
  });
  Expect.equals(length, index);

  Expect.isFalse(indexed.contains(0));
  Expect.isFalse(indexed.contains((start - 1, 0)));
  Expect.isFalse(indexed.contains((start + length, 0)));

  if (values.isNotEmpty) {
    Expect.isFalse(indexed.contains(values.first));
    Expect.equals((start, values.first), indexed.first);
    Expect.equals((start + length - 1, values.last), indexed.last);
    for (var i = 0; i < length; i++) {
      Expect.equals((start + i, values[i]), indexed.elementAt(i));
      Expect.isTrue(indexed.contains((start + i, values[i])));
    }
    Expect.isFalse(indexed.contains((start - 1, values.first)));
    Expect.isFalse(indexed.contains((start + length, values.last)));
    if (length == 1) {
      Expect.equals((start, values.single), indexed.single);
    } else if (!rec) {
      Expect.throws<StateError>(() => indexed.single);
      // More than one element, so test skip/take.
      testRec("$name.skip(1)", values.sublist(1), indexed.skip(1), 1, true);
      testRec(
        "$name.take(l-1)",
        values.sublist(0, length - 1),
        indexed.take(length - 1),
        0,
        true,
      );
      if (length > 2) {
        testRec(
          "$name.skip(1).take(l-2)",
          values.sublist(1, length - 1),
          indexed.skip(1).take(length - 2),
          1,
          true,
        );
        testRec(
          "$name.take(l-1).skip(1)",
          values.sublist(1, length - 1),
          indexed.take(length - 1).skip(1),
          1,
          true,
        );
      }
    }
  }
}

/// Generates an iterable with [length] elements.
///
/// The elements are 1, ..., [length], except that if `isValue` returns
/// `false` for a number, it's replaced by `null`.
/// If [throwAt] is provided, the iterable throws an `UnimplementedError`
/// (which shouldn't conflict with an actual error) instead of emitting
/// a value at the [throwAt] index.
Iterable<int?> numbers(
  int length, {
  bool Function(int) where = all,
  int? throwAt,
}) sync* {
  for (var i = 1; i <= length; i++) {
    if (i == throwAt) throw UnimplementedError("Error");
    yield where(i) ? i : null;
  }
}

/// Iterable which throws only when accessing [current].
///
/// Used to test that operations that don't need the value,
/// also don't read it.
///
/// (Could also be achieved with
/// ```
/// _source.toList().map((x) => x == _throwAt ? throw ... : x));
/// ```
/// but that assumes optimization behavior that is not necessarily tested.)
class CurrentThrowIterable<T> extends Iterable<T> {
  final T _throwAt;
  final Iterable<T> _source;
  CurrentThrowIterable(this._source, this._throwAt);
  Iterator<T> get iterator =>
      CurrentThrowIterator<T>(_source.iterator, _throwAt);
}

class CurrentThrowIterator<T> implements Iterator<T> {
  final T _throwAt;
  Iterator<T> _source;
  CurrentThrowIterator(this._source, this._throwAt);
  bool moveNext() => _source.moveNext();
  T get current {
    var result = _source.current;
    if (result == _throwAt) throw UnimplementedError("Error");
    return result;
  }
}

bool none(_) => false;
bool all(_) => true;
bool even(int n) => n.isEven;
bool Function(int) only(int n1) =>
    (int n2) => n1 == n2;
