// Copyright (c) 2013, 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.
//
// VMOptions=

// Tests of hash set behavior, with focus in iteration and concurrent
// modification errors.

library hash_map2_test;

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

testSet(Set newSet(), Set newSetFrom(Iterable from)) {
  Set gen(int from, int to) =>
      new Set.from(new Iterable.generate(to - from, (n) => n + from));

  bool odd(n) => (n & 1) == 1;
  bool even(n) => (n & 1) == 0;

  {
    // Test growing to largish capacity.
    Set set = newSet();

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

    set.addAll(gen(256, 512));
    set.addAll(newSetFrom(gen(512, 1000)));
    Expect.equals(1000, set.length);

    // Remove half.
    for (int i = 0; i < 1000; i += 2) set.remove(i);
    Expect.equals(500, set.length);
    Expect.isFalse(set.any(even));
    Expect.isTrue(set.every(odd));

    // Re-add all.
    set.addAll(gen(0, 1000));
    Expect.equals(1000, set.length);
  }

  {
    // Test having many deleted elements.
    Set set = newSet();
    set.add(0);
    for (int i = 0; i < 1000; i++) {
      set.add(i + 1);
      set.remove(i);
      Expect.equals(1, set.length);
    }
  }

  {
    // Test having many elements with same hashCode
    Set set = newSet();
    for (int i = 0; i < 1000; i++) {
      set.add(new BadHashCode());
    }
    Expect.equals(1000, set.length);
  }

  {
    // Check concurrent modification
    Set set = newSet()..add(0)..add(1);

    {
      // Test adding before a moveNext.
      Iterator iter = set.iterator;
      iter.moveNext();
      set.add(1); // Updating existing key isn't a modification.
      iter.moveNext();
      set.add(2);
      Expect.throws(iter.moveNext, (e) => e is Error);
    }

    {
      // Test adding after last element.
      Iterator iter = set.iterator;
      Expect.equals(3, set.length);
      iter.moveNext();
      iter.moveNext();
      iter.moveNext();
      set.add(3);
      Expect.throws(iter.moveNext, (e) => e is Error);
    }

    {
      // Test removing during iteration.
      Iterator iter = set.iterator;
      iter.moveNext();
      set.remove(1000); // Not a modification if it's not there.
      iter.moveNext();
      int n = iter.current;
      set.remove(n);
      // Removing doesn't change current.
      Expect.equals(n, iter.current);
      Expect.throws(iter.moveNext, (e) => e is Error);
    }

    {
      // Test removing after last element.
      Iterator iter = set.iterator;
      Expect.equals(3, set.length);
      iter.moveNext();
      iter.moveNext();
      iter.moveNext();
      int n = iter.current;
      set.remove(n);
      // Removing doesn't change current.
      Expect.equals(n, iter.current);
      Expect.throws(iter.moveNext, (e) => e is Error);
    }

    {
      // Test that updating value doesn't cause error.
      Iterator iter = set.iterator;
      Expect.equals(2, set.length);
      iter.moveNext();
      int n = iter.current;
      set.add(n);
      iter.moveNext();
      Expect.isTrue(set.contains(iter.current));
    }

    {
      // Check adding many existing values isn't considered modification.
      Set set2 = newSet();
      for (var value in set) {
        set2.add(value);
      }
      Iterator iter = set.iterator;
      set.addAll(set2);
      // Shouldn't throw.
      iter.moveNext();
    }
  }

  {
    // Check that updating existing elements is not a modification.
    // This must be the case even if the underlying data structure is
    // nearly full.
    for (int i = 1; i < 128; i++) {
      // Create maps of different sizes, some of which should be
      // at a limit of the underlying data structure.
      Set set = newSetFrom(gen(0, i));
      Iterator iter = set.iterator;
      for (int j = 0; j < i; j++) {
        set.add(j);
      }
      iter.moveNext(); // Should not throw.

      for (int j = 1; j < i; j++) {
        set.remove(j);
      }
      iter = set.iterator;
      set.add(0);
      iter.moveNext(); // Should not throw.
    }
  }

  {
    // Check that null can be in the set.
    Set set = newSet();
    set.add(null);
    Expect.equals(1, set.length);
    Expect.isTrue(set.contains(null));
    Expect.isNull(set.first);
    Expect.isNull(set.last);
    set.add(null);
    Expect.equals(1, set.length);
    Expect.isTrue(set.contains(null));
    set.remove(null);
    Expect.isTrue(set.isEmpty);
    Expect.isFalse(set.contains(null));

    // Created using Set.from.
    set = newSetFrom([null]);
    Expect.equals(1, set.length);
    Expect.isTrue(set.contains(null));
    Expect.isNull(set.first);
    Expect.isNull(set.last);
    set.add(null);
    Expect.equals(1, set.length);
    Expect.isTrue(set.contains(null));
    set.remove(null);
    Expect.isTrue(set.isEmpty);
    Expect.isFalse(set.contains(null));

    // Set that grows with null in it.
    set = newSetFrom([1, 2, 3, null, 4, 5, 6]);
    Expect.equals(7, set.length);
    for (int i = 7; i < 128; i++) {
      set.add(i);
    }
    Expect.equals(128, set.length);
    Expect.isTrue(set.contains(null));
    set.add(null);
    Expect.equals(128, set.length);
    Expect.isTrue(set.contains(null));
    set.remove(null);
    Expect.equals(127, set.length);
    Expect.isFalse(set.contains(null));
  }

  {
    // Check that addAll and clear works.
    Set set = newSet();
    set.addAll([]);
    Expect.isTrue(set.isEmpty);
    set.addAll([1, 3, 2]);
    Expect.equals(3, set.length);
    Expect.isTrue(set.contains(1));
    Expect.isTrue(set.contains(3));
    Expect.isTrue(set.contains(2));
    Expect.isFalse(set.contains(4));
    set.clear();
    Expect.isTrue(set.isEmpty);
  }

  {
    // Check that removeWhere and retainWhere work.
    Set set = newSetFrom([1, 2, 3]);
    set.removeWhere((each) => each == 2);
    Expect.equals(2, set.length);
    Expect.isTrue(set.contains(1));
    Expect.isFalse(set.contains(2));
    Expect.isTrue(set.contains(3));
    set.retainWhere((each) => each == 3);
    Expect.equals(1, set.length);
    Expect.isFalse(set.contains(1));
    Expect.isFalse(set.contains(2));
    Expect.isTrue(set.contains(3));
  }

  {
    // Test lookup
    Set set = newSet();
    var m1a = new Mutable(1);
    var m1b = new Mutable(1);
    var m2a = new Mutable(2);
    var m2b = new Mutable(2);
    Expect.isNull(set.lookup(m1a));
    Expect.isNull(set.lookup(m1b));
    set.add(m1a);
    Expect.identical(m1a, set.lookup(m1a));
    Expect.identical(m1a, set.lookup(m1b));

    Expect.isNull(set.lookup(m2a));
    Expect.isNull(set.lookup(m2b));
    set.add(m2a);
    Expect.identical(m2a, set.lookup(m2a));
    Expect.identical(m2a, set.lookup(m2b));

    set.add(m2b); // Adding doesn't change element.
    Expect.identical(m2a, set.lookup(m2a));
    Expect.identical(m2a, set.lookup(m2b));

    set.remove(m1a);
    set.add(m1b);
    Expect.identical(m1b, set.lookup(m1a));
    Expect.identical(m1b, set.lookup(m1b));

    set.add(1);
    Expect.identical(1, set.lookup(1.0));
    set.add(-0.0);
    Expect.identical(-0.0, set.lookup(0.0));
  }

  {
    // Test special hash codes
    Set set = newSet();
    List keys = [];
    // Powers of two
    for (int i = 63; i >= 2; --i) {
      keys.add(new Mutable(math.pow(2, i) as int));
    }
    for (var key in keys) {
      Expect.isTrue(set.add(key));
    }
    for (var key in keys) {
      Expect.isTrue(set.contains(key));
    }
  }
}

void testIdentitySet(Set create()) {
  Set set = create();
  set.add(1);
  set.add(2);
  set.add(1); // Integers are identical if equal.
  Expect.equals(2, set.length);
  var complex = 4;
  complex = set.length == 2 ? complex ~/ 4 : 87; // Avoid compile-time constant.
  Expect.isTrue(set.contains(complex)); // 1 is in set, even if computed.
  set.clear();

  // All compile time constants are identical to themselves.
  var constants = [
    double.infinity,
    double.nan, -0.0, //# 01: ok
    0.0, 42, "", null, false, true, #bif, testIdentitySet
  ];
  set.addAll(constants);
  Expect.equals(constants.length, set.length);
  for (var c in constants) {
    Expect.isTrue(set.contains(c), "constant: $c");
  }
  Expect.isTrue(set.containsAll(constants), "constants: $set");
  set.clear();

  var m1 = new Mutable(1);
  var m2 = new Mutable(2);
  var m3 = new Mutable(3);
  var m4 = new Mutable(2); // Equal to m2, but not identical.
  set.addAll([m1, m2, m3, m4]);
  Expect.equals(4, set.length);
  Expect.equals(3, m3.hashCode);
  m3.id = 1;
  Expect.equals(1, m3.hashCode);
  // Changing hashCode doesn't affect lookup.
  Expect.isTrue(set.contains(m3));
  Expect.isTrue(set.contains(m1));
  set.remove(m3);
  Expect.isFalse(set.contains(m3));
  Expect.isTrue(set.contains(m1));

  Expect.identical(m1, set.lookup(m1));
  Expect.identical(null, set.lookup(m3));
}

void main() {
  testSet(() => new Set(), (m) => new Set.from(m));
  testSet(() => new HashSet(), (m) => new HashSet.from(m));
  testSet(() => new LinkedHashSet(), (m) => new LinkedHashSet.from(m));
  testIdentitySet(() => new Set.identity());
  testIdentitySet(() => new HashSet.identity());
  testIdentitySet(() => new LinkedHashSet.identity());
  testIdentitySet(() => new HashSet(
      equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x)));
  testIdentitySet(() => new LinkedHashSet(
      equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x)));
}

class BadHashCode {
  static int idCounter = 0;
  final int id;
  BadHashCode() : id = idCounter++;
  int get hashCode => 42;
  // operator == is identity.
  // Can't make a bad compareTo that isn't invalid.
  int compareTo(BadHashCode other) => id - other.id;
}

class Mutable {
  int id;
  Mutable(this.id);
  int get hashCode => id;
  bool operator ==(other) => other is Mutable && id == other.id;
}
