// 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;
  }
}

main() {
  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,
  };
  for (var data in [
    const <int>[],
    const <int>[1],
    const <int>[1, 2, 3]
  ]) {
    conversions.forEach((name, c) {
      test(data, c(data).whereType<int>(), "$name#${data.length}.wt<int>");
      test(data, c(data).whereType<num>(), "$name#${data.length}.wt<num>");
      test([], c(data).whereType<Null>(), "$name#${data.length}.wt<Null>");
    });
  }

  test([1, 0.1], ["a", 1, new Object(), 0.1, null].whereType<num>(), "mixed");

  var o = new Object();
  var a = new A();
  var b = new B();
  var c = new C();
  var d = new D();
  var n = null;
  test([o, a, b, c, d, n], [o, a, b, c, d, n].whereType<Object>(), "Object");
  test([a, b, c, d], [o, a, b, c, d, n].whereType<A>(), "A");
  test([b, d], [o, a, b, c, d, n].whereType<B>(), "B");
  test([c, d], [o, a, b, c, d, n].whereType<C>(), "C");
  test([d], [o, a, b, c, d, n].whereType<D>(), "D");
  test([n], [o, a, b, c, d, n].whereType<Null>(), "Null");

  test([d], <B>[d].whereType<C>(), "Unrelated");
}

class A {}

class B implements A {}

class C implements A {}

class D implements B, C {}

List<int> toConst(List<int> elements) => elements; // Argument is const.
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;
