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

// @dart = 2.9

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;
  testForEach(Object 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.
  testMap(Object val) {
    return (val as int) * (val as int);
  }

  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.
  testFilter(Object 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.
  testEvery(Object 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.
  testSome(Object 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(10);
  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(Object 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(Object 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();
}
