// 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.

library set_test;

import 'package:expect/expect.dart';
import "dart:collection";

void testMain(Set create()) {
  testInts(create);
  testStrings(create);
  testInts(() => create().toSet());
  testStrings(() => create().toSet());
}

void testInts(Set create()) {
  Set set = create();

  testLength(0, set);
  Expect.isTrue(set.add(1));
  testLength(1, set);
  Expect.isTrue(set.contains(1));

  Expect.isFalse(set.add(1));
  testLength(1, set);
  Expect.isTrue(set.contains(1));

  Expect.isTrue(set.remove(1));
  testLength(0, set);
  Expect.isFalse(set.contains(1));

  Expect.isFalse(set.remove(1));
  testLength(0, set);
  Expect.isFalse(set.contains(1));

  for (int i = 0; i < 10; i++) {
    set.add(i);
  }

  testLength(10, set);
  for (int i = 0; i < 10; i++) {
    Expect.isTrue(set.contains(i));
  }

  testLength(10, set);

  for (int i = 10; i < 20; i++) {
    Expect.isFalse(set.contains(i));
  }

  // Test Set.forEach.
  int sum = 0;
  void testForEach(dynamic val) {
    sum += ((val as int) + 1);
  }

  set.forEach(testForEach);
  Expect.equals(10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1, sum);

  Expect.isTrue(set.containsAll(set));

  // Test Set.map.
  int testMap(dynamic val) {
    return (val as int) * val;
  }

  Set mapped = set.map(testMap).toSet();
  Expect.equals(10, mapped.length);

  Expect.isTrue(mapped.contains(0));
  Expect.isTrue(mapped.contains(1));
  Expect.isTrue(mapped.contains(4));
  Expect.isTrue(mapped.contains(9));
  Expect.isTrue(mapped.contains(16));
  Expect.isTrue(mapped.contains(25));
  Expect.isTrue(mapped.contains(36));
  Expect.isTrue(mapped.contains(49));
  Expect.isTrue(mapped.contains(64));
  Expect.isTrue(mapped.contains(81));

  sum = 0;
  set.forEach(testForEach);
  Expect.equals(10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1, sum);

  sum = 0;

  mapped.forEach(testForEach);
  Expect.equals(1 + 2 + 5 + 10 + 17 + 26 + 37 + 50 + 65 + 82, sum);

  // Test Set.filter.
  bool testFilter(dynamic val) {
    return (val as int).isEven;
  }

  Set filtered = set.where(testFilter).toSet();

  Expect.equals(5, filtered.length);

  Expect.isTrue(filtered.contains(0));
  Expect.isTrue(filtered.contains(2));
  Expect.isTrue(filtered.contains(4));
  Expect.isTrue(filtered.contains(6));
  Expect.isTrue(filtered.contains(8));

  sum = 0;
  filtered.forEach(testForEach);
  Expect.equals(1 + 3 + 5 + 7 + 9, sum);

  Expect.isTrue(set.containsAll(filtered));

  // Test Set.every.
  bool testEvery(dynamic val) {
    return ((val as int) < 10);
  }

  Expect.isTrue(set.every(testEvery));
  Expect.isTrue(filtered.every(testEvery));

  filtered.add(10);
  Expect.isFalse(filtered.every(testEvery));

  // Test Set.some.
  bool testSome(dynamic val) {
    return (val == 4);
  }

  Expect.isTrue(set.any(testSome));
  Expect.isTrue(filtered.any(testSome));
  filtered.remove(4);
  Expect.isFalse(filtered.any(testSome));

  // Test Set.intersection.
  Set intersection = set.intersection(filtered);
  Expect.isTrue(set.contains(0));
  Expect.isTrue(set.contains(2));
  Expect.isTrue(set.contains(6));
  Expect.isTrue(set.contains(8));
  Expect.isFalse(intersection.contains(1));
  Expect.isFalse(intersection.contains(3));
  Expect.isFalse(intersection.contains(4));
  Expect.isFalse(intersection.contains(5));
  Expect.isFalse(intersection.contains(7));
  Expect.isFalse(intersection.contains(9));
  Expect.isFalse(intersection.contains(10));
  Expect.equals(4, intersection.length);

  Expect.isTrue(set.containsAll(intersection));
  Expect.isTrue(filtered.containsAll(intersection));

  // Test Set.union.
  Set twice = create()..addAll([0, 2, 4, 6, 8, 10, 12, 14]);
  Set thrice = create()..addAll([0, 3, 6, 9, 12, 15]);
  Set union = twice.union(thrice);
  Expect.equals(11, union.length);
  for (int i = 0; i < 16; i++) {
    Expect.equals(i.isEven || (i % 3) == 0, union.contains(i));
  }

  // Test Set.difference.
  Set difference = twice.difference(thrice);
  Expect.equals(5, difference.length);
  for (int i = 0; i < 16; i++) {
    Expect.equals(i.isEven && (i % 3) != 0, difference.contains(i));
  }
  Expect.isTrue(twice.difference(thrice).difference(twice).isEmpty);

  // Test Set.difference with non-element type.
  Set diffSet = create()..addAll([0, 1, 2, 499, 999]);
  Set<Object> objectSet = new Set<Object>();
  objectSet.add("foo");
  objectSet.add(499);
  Set diffResult = diffSet.difference(objectSet);
  Expect.equals(4, diffResult.length);
  for (int value in [0, 1, 2, 999]) {
    Expect.isTrue(diffResult.contains(value));
  }

  // Test Set.addAll.
  List list = new List.filled(10, null);
  for (int i = 0; i < 10; i++) {
    list[i] = i + 10;
  }
  set.addAll(list);
  testLength(20, set);
  for (int i = 0; i < 20; i++) {
    Expect.isTrue(set.contains(i));
  }

  // Test Set.removeAll
  set.removeAll(list);
  testLength(10, set);
  for (int i = 0; i < 10; i++) {
    Expect.isTrue(set.contains(i));
  }
  for (int i = 10; i < 20; i++) {
    Expect.isFalse(set.contains(i));
  }

  // Test Set.clear.
  set.clear();
  testLength(0, set);
  Expect.isTrue(set.add(11));
  testLength(1, set);

  // Test Set.toSet.
  set.add(1);
  set.add(21);
  testLength(3, set);
  var set2 = set.toSet();
  testLength(3, set2);
  Expect.listEquals(set.toList(), set2.toList());
  set.add(31);
  testLength(4, set);
  testLength(3, set2);

  set2 = set.toSet()..clear();
  testLength(0, set2);
  Expect.isTrue(set2.add(11));
  Expect.isTrue(set2.add(1));
  Expect.isTrue(set2.add(21));
  Expect.isTrue(set2.add(31));
  testLength(4, set2);
  Expect.listEquals(set.toList(), set2.toList());

  set2 = (set.toSet()..clear()).toSet(); // Cloning empty set shouldn't fail.
  testLength(0, set2);
}

void testLength(int length, Set set) {
  Expect.equals(length, set.length);
  (length == 0 ? Expect.isTrue : Expect.isFalse)(set.isEmpty);
  (length != 0 ? Expect.isTrue : Expect.isFalse)(set.isNotEmpty);
  if (length == 0) {
    for (var e in set) {
      Expect.fail("contains element when iterated: $e");
    }
  }
  (length == 0 ? Expect.isFalse : Expect.isTrue)(set.iterator.moveNext());
}

void testStrings(Set create()) {
  var set = create();
  var strings = ["foo", "bar", "baz", "qux", "fisk", "hest", "svin", "pigvar"];
  set.addAll(strings);
  testLength(8, set);
  set.removeAll(strings.where((x) => x.length == 3));
  testLength(4, set);
  Expect.isTrue(set.add("bar"));
  Expect.isTrue(set.add("qux"));
  testLength(6, set);
  set.addAll(strings);
  testLength(8, set);
  set.removeWhere((x) => x.length != 3);
  testLength(4, set);
  set.retainWhere((x) => x[1] == "a");
  testLength(2, set);
  Expect.isTrue(set.containsAll(["baz", "bar"]));

  set = set.union(strings.where((x) => x.length != 3).toSet());
  testLength(6, set);
  set = set.intersection(["qux", "baz", "fisk", "egern"].toSet());
  testLength(2, set);
  Expect.isTrue(set.containsAll(["baz", "fisk"]));
}

void testTypeAnnotations(Set<int> set) {
  set.add(0);
  set.add(999);
  set.add(0x800000000);
  set.add(0x20000000000000);
  Expect.isFalse(set.contains("not an it"));
  Expect.isFalse(set.remove("not an it"));
  Expect.isFalse(set.containsAll(["Not an int", "Also no an int"]));

  testLength(4, set);
  set.removeAll(["Not an int", 999, "Also no an int"]);
  testLength(3, set);
  set.retainAll(["Not an int", 0, "Also no an int"]);
  testLength(1, set);
}

void testRetainWhere(
    Set<CE> create(
        [CEEq? equals, CEHash? hashCode, ValidKey? validKey, CECompare? compare])) {
  // The retainWhere method must not collapse the argument Iterable
  // in a way that doesn't match the equality of the set.
  // It must not throw away equal elements that are different in the
  // equality of the set.
  // It must not consider objects to be not there if they are equal
  // in the equality of the set.

  // If set equality is natural equality, using different but equal objects
  // must work. Can't use an identity set internally (as was done at some point
  // during development).
  var set = create();
  set.addAll([new CE(0), new CE(1), new CE(2)]);
  Expect.equals(3, set.length); // All different.
  set.retainAll([new CE(0), new CE(2)]);
  Expect.equals(2, set.length);
  Expect.isTrue(set.contains(new CE(0)));
  Expect.isTrue(set.contains(new CE(2)));

  // If equality of set is identity, we can't internally use a non-identity
  // based set because it might throw away equal objects that are not identical.
  var elems = [new CE(0), new CE(1), new CE(2), new CE(0)];
  set = create(identical, null, null, identityCompare);
  set.addAll(elems);
  Expect.equals(4, set.length);
  set.retainAll([elems[0], elems[2], elems[3]]);
  Expect.equals(3, set.length);
  Expect.isTrue(set.contains(elems[0]));
  Expect.isTrue(set.contains(elems[2]));
  Expect.isTrue(set.contains(elems[3]));

  // If set equality is less precise than equality, we must not use equality
  // internally to see if the element is there:
  set = create(customEq(3), customHash(3), validKey, customCompare(3));
  set.addAll([new CE(0), new CE(1), new CE(2)]);
  Expect.equals(3, set.length);
  set.retainAll([new CE(3), new CE(5)]);
  Expect.equals(2, set.length);
  Expect.isTrue(set.contains(new CE(6)));
  Expect.isTrue(set.contains(new CE(8)));

  // It shouldn't matter if the input is a set.
  set.clear();
  set.addAll([new CE(0), new CE(1), new CE(2)]);
  Expect.equals(3, set.length);
  set.retainAll(new Set.from([new CE(3), new CE(5)]));
  Expect.equals(2, set.length);
  Expect.isTrue(set.contains(new CE(6)));
  Expect.isTrue(set.contains(new CE(8)));
}

void testDifferenceIntersection(create([equals, hashCode, validKey, compare])) {
  // Test that elements of intersection comes from receiver set.
  CE ce1a = new CE(1);
  CE ce1b = new CE(1);
  CE ce2 = new CE(2);
  CE ce3 = new CE(3);
  Expect.equals(ce1a, ce1b); // Sanity check.

  var set1 = create();
  var set2 = create();
  set1.add(ce1a);
  set1.add(ce2);
  set2.add(ce1b);
  set2.add(ce3);

  var difference = set1.difference(set2);
  testLength(1, difference);
  Expect.identical(ce2, difference.lookup(ce2));

  difference = set2.difference(set1);
  testLength(1, difference);
  Expect.identical(ce3, difference.lookup(ce3));

  // Difference uses other.contains to check for equality.
  var set3 = create(identical, identityHashCode, null, identityCompare);
  set3.add(ce1b);
  difference = set1.difference(set3);
  testLength(2, difference); // ce1a is not identical to element in set3.
  Expect.identical(ce1a, difference.lookup(ce1a));
  Expect.identical(ce2, difference.lookup(ce2));

  // Intersection always takes elements from receiver set.
  var intersection = set1.intersection(set2);
  testLength(1, intersection);
  Expect.identical(ce1a, intersection.lookup(ce1a));

  intersection = set1.intersection(set3);
  testLength(0, intersection);
}

// Objects that are equal based on data.
class CE implements Comparable<CE> {
  final int id;
  const CE(this.id);
  int get hashCode => id;
  bool operator ==(Object other) => other is CE && id == other.id;
  int compareTo(CE other) => id - other.id;
  String toString() => "CE($id)";
}

typedef int CECompare(CE e1, CE e2);
typedef int CEHash(CE e1);
typedef bool CEEq(CE e1, CE e2);
typedef bool ValidKey(dynamic o);
// Equality of Id objects based on id modulo value.
CEEq customEq(int mod) => (CE e1, CE e2) => ((e1.id - e2.id) % mod) == 0;
CEHash customHash(int mod) => (CE e) => e.id % mod;
CECompare customCompare(int mod) =>
    (CE e1, CE e2) => (e1.id % mod) - (e2.id % mod);
bool validKey(dynamic o) => o is CE;
final customId = new Map<dynamic, dynamic>.identity();
int counter = 0;
int identityCompare(e1, e2) {
  if (identical(e1, e2)) return 0;
  int i1 = customId.putIfAbsent(e1, () => ++counter);
  int i2 = customId.putIfAbsent(e2, () => ++counter);
  return i1 - i2;
}

void testIdentity(Set create()) {
  Set set = create();
  var e1 = new CE(0);
  var e2 = new CE(0);
  Expect.equals(e1, e2);
  Expect.isFalse(identical(e1, e2));

  testLength(0, set);
  set.add(e1);
  testLength(1, set);
  Expect.isTrue(set.contains(e1));
  Expect.isFalse(set.contains(e2));

  set.add(e2);
  testLength(2, set);
  Expect.isTrue(set.contains(e1));
  Expect.isTrue(set.contains(e2));

  var set2 = set.toSet();
  testLength(2, set2);
  Expect.isTrue(set2.contains(e1));
  Expect.isTrue(set2.contains(e2));
}

void testIntSetFrom(setFrom) {
  List<num> numList = [2, 3, 5, 7, 11, 13];

  Set<int> set1 = setFrom(numList);
  Expect.listEquals(numList, set1.toList()..sort());

  Set<num> numSet = numList.toSet();
  Set<int> set2 = setFrom(numSet);
  Expect.listEquals(numList, set2.toList()..sort());

  Iterable<num> numIter = numList.where((x) => true);
  Set<int> set3 = setFrom(numIter);
  Expect.listEquals(numList, set3.toList()..sort());

  Set<int> set4 = setFrom(new Iterable.generate(0));
  Expect.isTrue(set4.isEmpty);
}

void testCESetFrom(setFrom) {
  var ceList = [
    new CE(2),
    new CE(3),
    new CE(5),
    new CE(7),
    new CE(11),
    new CE(13)
  ];

  Set<CE> set1 = setFrom(ceList);
  Expect.listEquals(ceList, set1.toList()..sort());

  Set<CE> ceSet = ceList.toSet();
  Set<CE> set2 = setFrom(ceSet);
  Expect.listEquals(ceList, set2.toList()..sort());

  Iterable<CE> ceIter = ceList.where((x) => true);
  Set<CE> set3 = setFrom(ceIter);
  Expect.listEquals(ceList, set3.toList()..sort());

  Set<CE> set4 = setFrom(new Iterable.generate(0));
  Expect.isTrue(set4.isEmpty);
}

class A {}

class B {}

class C implements A, B {}

void testASetFrom(setFrom) {
  List<B> bList = <B>[new C()];
  // Set.from allows to cast elements.
  Set<A> aSet = setFrom(bList);
  Expect.isTrue(aSet.length == 1);
}

void testUnmodifiable(Set source) {
  var unmodifiable = Set.unmodifiable(source);

  Expect.throwsUnsupportedError(() {
    unmodifiable.add(3);
  }, "add");

  Expect.throwsUnsupportedError(() {
    unmodifiable.addAll({1, 2, 3});
  }, "addAll");

  Expect.throwsUnsupportedError(() {
    unmodifiable.addAll(<int>{});
  }, "addAll empty");

  Expect.throwsUnsupportedError(() {
    unmodifiable.remove(3);
  }, "remove");

  Expect.throwsUnsupportedError(() {
    unmodifiable.removeAll({1, 2, 3});
  }, "removeAll");

  Expect.throwsUnsupportedError(() {
    unmodifiable.removeAll(<int>{});
  }, "removeAll empty");

  Expect.throwsUnsupportedError(() {
    unmodifiable.retainAll({1, 2, 3});
  }, "retainAll");

  Expect.throwsUnsupportedError(() {
    unmodifiable.retainAll(<int>{});
  }, "retainAll empty");

  Expect.throwsUnsupportedError(() {
    unmodifiable.removeWhere((_) => true);
  }, "removeWhere");

  Expect.throwsUnsupportedError(() {
    unmodifiable.retainWhere((_) => false);
  }, "retainWhere");

  Expect.throwsUnsupportedError(() {
    unmodifiable.clear();
  }, "clear");
}

void testUnmodifiableSetIsNotUpdatedIfSourceSetIsUpdated() {
  var modifiable = {1};
  var unmodifiable = Set.unmodifiable(modifiable);

  modifiable.add(2);
  Expect.notEquals(modifiable.length, unmodifiable.length);
  Expect.setEquals({2}, modifiable.difference(unmodifiable));
  modifiable.removeAll({1, 2});
  Expect.setEquals({1}, unmodifiable.difference(modifiable));
  Expect.setEquals({1}, unmodifiable);
}

main() {
  testMain(() => new HashSet());
  testMain(() => new LinkedHashSet());
  testMain(() => new HashSet.identity());
  testMain(() => new LinkedHashSet.identity());
  testMain(() => new HashSet(equals: identical));
  testMain(() => new LinkedHashSet(equals: identical));
  testMain(() => new HashSet(
      equals: (a, b) => a == b,
      hashCode: (a) => -a.hashCode,
      isValidKey: (a) => true));
  testMain(() => new LinkedHashSet(
      equals: (a, b) => a == b,
      hashCode: (a) => -a.hashCode,
      isValidKey: (a) => true));
  testMain(() => new SplayTreeSet());

  testIdentity(() => new HashSet.identity());
  testIdentity(() => new LinkedHashSet.identity());
  testIdentity(() => new HashSet(equals: identical));
  testIdentity(() => new LinkedHashSet(equals: identical));
  testIdentity(() => new SplayTreeSet(identityCompare));

  testTypeAnnotations(new HashSet<int>());
  testTypeAnnotations(new LinkedHashSet<int>());
  testTypeAnnotations(new HashSet<int>(equals: identical));
  testTypeAnnotations(new LinkedHashSet<int>(equals: identical));
  testTypeAnnotations(new HashSet<int>(
      equals: (int a, int b) => a == b,
      hashCode: (int a) => a.hashCode,
      isValidKey: (a) => a is int));
  testTypeAnnotations(new LinkedHashSet<int>(
      equals: (int a, int b) => a == b,
      hashCode: (int a) => a.hashCode,
      isValidKey: (a) => a is int));
  testTypeAnnotations(new SplayTreeSet<int>());

  testRetainWhere(([equals, hashCode, validKey, comparator]) =>
      new HashSet(equals: equals, hashCode: hashCode, isValidKey: validKey));
  testRetainWhere(([equals, hashCode, validKey, comparator]) =>
      new LinkedHashSet(
          equals: equals, hashCode: hashCode, isValidKey: validKey));
  testRetainWhere(([equals, hashCode, validKey, comparator]) =>
      new SplayTreeSet(comparator, validKey));

  testDifferenceIntersection(([equals, hashCode, validKey, comparator]) =>
      new HashSet(equals: equals, hashCode: hashCode, isValidKey: validKey));
  testDifferenceIntersection(([equals, hashCode, validKey, comparator]) =>
      new LinkedHashSet(
          equals: equals, hashCode: hashCode, isValidKey: validKey));
  testDifferenceIntersection(([equals, hashCode, validKey, comparator]) =>
      new SplayTreeSet(comparator, validKey));

  testIntSetFrom((x) => new Set<int>.from(x));
  testIntSetFrom((x) => new HashSet<int>.from(x));
  testIntSetFrom((x) => new LinkedHashSet<int>.from(x));
  testIntSetFrom((x) => new SplayTreeSet<int>.from(x));

  testCESetFrom((x) => new Set<CE>.from(x));
  testCESetFrom((x) => new HashSet<CE>.from(x));
  testCESetFrom((x) => new LinkedHashSet<CE>.from(x));
  testCESetFrom((x) => new SplayTreeSet<CE>.from(x));

  testCESetFrom(
      (x) => new SplayTreeSet<CE>.from(x, customCompare(20), validKey));
  testCESetFrom((x) => new SplayTreeSet<CE>.from(x, identityCompare));

  testASetFrom((x) => new Set<A>.from(x));
  testASetFrom((x) => new HashSet<A>.from(x));
  testASetFrom((x) => new LinkedHashSet<A>.from(x));
  testASetFrom((x) => new SplayTreeSet<A>.from(x, identityCompare));

  testUnmodifiable({1});
  testUnmodifiableSetIsNotUpdatedIfSourceSetIsUpdated();
}
