// Copyright (c) 2020, 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";
import "package:expect/expect.dart";
import 'cast_helper.dart';

void main() {
  testDowncastDirectAccess();
  testDowncastNoDirectAccess();
  testDowncastUntouchableElements();
  testUpcast();
}

void testDowncastDirectAccess() {
  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);

  // An iterable that (likely) can do direct access.
  var dIterable = Iterable.castFrom<C, D>(iterable);

  Expect.throws(() => dIterable.first, null, "direct.first");
  Expect.equals(d, dIterable.elementAt(1));
  Expect.throws(() => dIterable.elementAt(2), null, "direct.2"); // E is not D.
  Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
  Expect.equals(null, dIterable.skip(3).elementAt(1));

  Expect.throws(() => dIterable.toList(), null, "direct.toList");
}

void testDowncastNoDirectAccess() {
  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);

  // An iterable that cannot do direct access.
  var dIterable = Iterable.castFrom<C, D>(iterable.where((_) => true));

  Expect.throws(() => dIterable.first, null, "nonDirect.first");
  Expect.equals(d, dIterable.elementAt(1));
  // E is not D.
  Expect.throws(() => dIterable.elementAt(2), null, "nonDirect.2");
  Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
  Expect.equals(null, dIterable.skip(3).elementAt(1));

  Expect.throws(() => dIterable.toList(), null, "nonDirect.toList");
}

void testDowncastUntouchableElements() {
  // Iterable that definitely won't survive accessing element 3.
  var iterable = new Iterable<C>.generate(
      elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
  var dIterable = Iterable.castFrom<C, D>(iterable);

  Expect.throws(() => dIterable.first, null, "untouchable.first");
  Expect.equals(d, dIterable.elementAt(1));
  Expect.throws(() => dIterable.elementAt(3), null, "untouchable.3");
  // Skip does not access element.
  Expect.equals(null, dIterable.skip(4).first);
  Expect.equals(null, dIterable.skip(3).elementAt(1));

  Expect.throws(() => dIterable.toList(), null, "untouchable.toList");
}

void testUpcast() {
  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);

  var objectIterable = Iterable.castFrom<C, Object>(iterable);
  Expect.listEquals(elements, objectIterable.toList());
}
