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

// @dart = 2.9

import "dart:collection" show Queue;
import "dart:typed_data" show Int32List;

import "package:expect/expect.dart";

// Tests behavior of result of an operation on a followedBy iterable.
test(List expects, Iterable iterable, [String name]) {
  try {
    Expect.isFalse(iterable is List, "$name is! List");
    Expect.isFalse(iterable is Set, "$name is! Set");
    Expect.isFalse(iterable is Queue, "$name is! Queue");
    if (expects.isNotEmpty) {
      Expect.equals(expects.first, iterable.first, "$name: first");
      Expect.equals(expects.last, iterable.last, "$name: last");
    } else {
      Expect.throwsStateError(() => iterable.first, "$name: first");
      Expect.throwsStateError(() => iterable.last, "$name: last");
    }
    var it = iterable.iterator;
    for (int index = 0; index < expects.length; index++) {
      Expect.isTrue(it.moveNext(), "$name: has element $index");
      var expect = expects[index];
      Expect.equals(expect, it.current, "$name at $index");
      Expect.equals(
          expect, iterable.elementAt(index), "$name: elementAt($index)");
      Expect.isTrue(iterable.contains(expect), "$name:contains $index");
    }
    Expect.isFalse(it.moveNext(),
        "$name: extra element at ${expects.length}: ${it.current}");
  } on Error {
    print("Failed during: $name");
    rethrow;
  }
}

// Tests various operations on the a followedBy iterable.
tests(List<int> expects, Iterable<int> follow, [String name]) {
  int length = expects.length;
  test(expects, follow, name);
  for (int i = 0; i <= length; i++) {
    test(expects.sublist(i), follow.skip(i), "$name.skip($i)");
  }
  for (int i = 0; i <= length; i++) {
    test(expects.sublist(0, i), follow.take(i), "$name.take($i)");
  }
  for (int i = 0; i <= length; i++) {
    for (int j = 0; j <= length - i; j++) {
      test(expects.sublist(i, i + j), follow.skip(i).take(j),
          "$name.skiptake($i,${i+j})");
      test(expects.sublist(i, i + j), follow.take(i + j).skip(i),
          "$name.takeskip($i,${i+j})");
    }
  }
}

// Tests various different types of iterables as first and second operand.
types(List expects, List<int> first, List<int> second, [String name]) {
  var conversions = <String, Iterable<int> Function(List<int>)>{
    "const": toConst,
    "list": toList,
    "unmod": toUnmodifiable,
    "set": toSet,
    "queue": toQueue,
    "eff-len-iter": toELIter,
    "non-eff-iter": toNEIter,
    "typed": toTyped,
    "keys": toKeys,
    "values": toValues,
  };
  conversions.forEach((n1, c1) {
    conversions.forEach((n2, c2) {
      tests(expects, c1(first).followedBy(c2(second)), "$name:$n1/$n2");
    });
  });
}

List<int> toConst(List<int> elements) => elements;
List<int> toList(List<int> elements) => elements.toList();
List<int> toUnmodifiable(List<int> elements) =>
    new List<int>.unmodifiable(elements);
Set<int> toSet(List<int> elements) => elements.toSet();
Queue<int> toQueue(List<int> elements) => new Queue<int>.from(elements);
// Creates an efficient-length iterable.
Iterable<int> toELIter(List<int> elements) => elements.map<int>((x) => x);
// Creates a non-efficient-length iterable.
Iterable<int> toNEIter(List<int> elements) => elements.where((x) => true);
List<int> toTyped(List<int> elements) => new Int32List.fromList(elements);
Iterable<int> toKeys(List<int> elements) =>
    new Map<int, int>.fromIterables(elements, elements).keys;
Iterable<int> toValues(List<int> elements) =>
    new Map<int, int>.fromIterables(elements, elements).values;

main() {
  types(<int>[], const <int>[], const <int>[], "0+0");
  types(<int>[1, 2, 3, 4], const <int>[], const <int>[1, 2, 3, 4], "0+4");
  types(<int>[1, 2, 3, 4], const <int>[1, 2], const <int>[3, 4], "2+2");
  types(<int>[1, 2, 3, 4], const <int>[1, 2, 3, 4], const <int>[], "4+0");
}
