// 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 'package:expect/variations.dart' as v;
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,
    0.0,
    42,
    "",
    null,
    false,
    true,
    #bif,
    testIdentitySet
  ];
  set.addAll(constants);
  if (v.jsNumbers) {
    // 0.0 and -0.0 are identical in JS.
    Expect.equals(constants.length - 1, set.length);
    Expect.isTrue(
        set.containsAll(constants.where((e) => !(e is double && e.isNaN))),
        "constants: $set");
  } else {
    Expect.equals(constants.length, set.length);
    Expect.isTrue(set.containsAll(constants), "constants: $set");
  }
  for (var c in constants) {
    // identical(double.nan, double.nan) == false in JS.
    if (v.jsNumbers && c is double && c.isNaN) continue;
    Expect.isTrue(set.contains(c), "constant: $c");
  }
  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;
}
