// Copyright (c) 2011, 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:collection";
import "dart:typed_data";
import "package:expect/expect.dart";

void main() {
  testIterable();
  testList();
}

final elements = <C>[c, d, e, f, null];

void testIterable() {
  var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
  // Down-cast
  {
    // An iterable that (likely) can do direct access.
    var dIterable = Iterable.castFrom<C, D>(iterable);

    Expect.throws(() => dIterable.first, null, "1.first");
    Expect.equals(d, dIterable.elementAt(1));
    Expect.throws(() => dIterable.elementAt(2), null, "1.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, "1.toList");
  }

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

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

    Expect.throws(() => dIterable2.toList(), null, "2.toList");
  }

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

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

    Expect.throws(() => dIterable3.toList(), null, "3.toList");
  }

  // Up-cast.
  {
    var oIterable4 = Iterable.castFrom<C, Object>(iterable);
    Expect.listEquals(elements, oIterable4.toList());
  }
}

void testList() {
  // Down-cast.
  var list = new List<C>.from(elements);
  var dList = List.castFrom<C, D>(list);

  Expect.throws(() => dList.first); // C is not D.
  Expect.equals(d, dList[1]);
  Expect.throws(() => dList[2]); // E is not D.
  Expect.equals(f, dList[3]);
  Expect.equals(null, dList.last);

  Expect.throws(() => dList.toList());

  dList[2] = d;
  Expect.equals(d, dList[2]); // Setting works.

  // Up-cast.
  var list2 = new List<C>.from(elements);
  var dList2 = List.castFrom<C, Object>(list2);
  Expect.listEquals(elements, dList2);
  Expect.throws(() => dList2[2] = new Object()); // Cannot set non-C.
  Expect.listEquals(elements, dList2);

  // Regression test.
  var list3 = <num>[4, 3, 2, 1];
  var dList3 = list3.retype<int>();
  dList3.sort(null);
  Expect.listEquals([1, 2, 3, 4], list3);
}

void testSet() {
  var set = new Set<C>.from(elements); // Linked HashSet.
  Expect.listEquals(elements, set.toList()); // Preserves order.

  var dSet = Set.castFrom<C, D>(set);

  // Preserves order.
  Expect.throws(() => dSet.first); // C is not D.
  Expect.equals(d, dSet.elementAt(1));
  Expect.throws(() => dSet.elementAt(2)); // E is not D.

  Expect.throws(() => dSet.toList());

  // Contains is not typed.
  var newC = new C();
  Expect.isFalse(dSet.contains(newC));
  dSet.add(newC);
  Expect.isTrue(dSet.contains(newC));

  Expect.equals(5, dSet.length);
  dSet.remove(newC);
  Expect.equals(5, dSet.length);
  dSet.remove(c); // Success, no type checks.
  Expect.equals(4, dSet.length);

  // Up-cast
  var set2 = new Set<C>.from(elements);
  var dSet2 = Set.castFrom<C, Object>(set2);

  var newObject = new Object();
  Expect.throws(() => dSet2.add(newObject));
  Expect.isFalse(dSet.contains(newObject));

  var toSet2 = dSet2.toSet();
  Expect.isTrue(toSet2 is LinkedHashSet<Object>);
  Expect.isTrue(toSet2 is! LinkedHashSet<C>);

  // Custom emptySet.

  var set3 = new Set<C>.from(elements);
  var dSet3 = Set.castFrom<C, Object>(set3, newSet: <T>() => new HashSet<T>());

  var toSet3 = dSet3.toSet();
  Expect.isTrue(toSet3 is HashSet<Object>);
  Expect.isTrue(toSet3 is HashSet<C>);
  Expect.isTrue(toSet3 is! LinkedHashSet<Object>);
}

void testMap() {
  var map = new Map.fromIterables(elements, elements);

  var dMap = Map.castFrom<C, C, D, D>(map);

  Expect.isTrue(dMap is Map<D, D>);

  Expect.equals(null, dMap[new C()]);
  Expect.throws(() => dMap[c]);
  Expect.isTrue(dMap.containsKey(c));
  Expect.equals(d, dMap[d]);
  Expect.throws(() => dMap[e]);
  Expect.equals(null, dMap[null]);

  Expect.equals(5, dMap.length);
  dMap.remove(c); // Success, no type checks along the way.
  Expect.equals(4, dMap.length);
  Expect.equals(null, dMap[c]);

  Expect.throws(() => dMap[c] = d);
  Expect.throws(() => dMap[d] = c);
  Expect.equals(4, dMap.length);

  Expect.isTrue(dMap.keys is Iterable<D>);
  Expect.isTrue(dMap.values is Iterable<D>);
  Expect.throws(() => dMap.keys.toList());
  Expect.throws(() => dMap.values.toList());
}

class C {}

class D extends C {}

class E extends C {}

class F implements D, E {}

final c = new C();
final d = new D();
final e = new E();
final f = new F();
