// Copyright (c) 2016, 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 enumset.test;

import 'package:compiler/src/util/enumset.dart';
import 'package:expect/expect.dart';

enum Enum { A, B, C, D, E, F, }

main() {
  testAddRemoveContains();
  testConstructorsIntersects();
}


void checkEnumSet(EnumSet<Enum> enumSet,
                 int expectedValue,
                 List<Enum> expectedValues,
                 String expectedToString) {
  Expect.equals(expectedValue, enumSet.value,
      "Unexpected EnumSet.value for ${enumSet.iterable(Enum.values)}");
  Expect.listEquals(expectedValues, enumSet.iterable(Enum.values).toList(),
      "Unexpected values: ${enumSet.iterable(Enum.values)}");
  Expect.equals(expectedValues.isEmpty, enumSet.isEmpty,
      "Unexpected EnumSet.isEmpty for ${enumSet.iterable(Enum.values)}");
  Expect.equals(expectedToString, enumSet.toString(),
      "Unexpected EnumSet.toString for ${enumSet.iterable(Enum.values)}");
  for (Enum value in Enum.values) {
    Expect.equals(expectedValues.contains(value), enumSet.contains(value),
        "Unexpected EnumSet.contains for $value in "
        "${enumSet.iterable(Enum.values)}");
  }
}

void testAddRemoveContains() {
  EnumSet<Enum> enumSet = new EnumSet<Enum>();

  void check(int expectedValue,
             List<Enum> expectedValues,
             String expectedToString) {
    checkEnumSet(enumSet, expectedValue, expectedValues, expectedToString);
  }

  check(0, [], '0');

  enumSet.add(Enum.B);
  check(2, [Enum.B], '10');

  enumSet.add(Enum.F);
  check(34, [Enum.F, Enum.B], '100010');

  enumSet.add(Enum.A);
  check(35, [Enum.F, Enum.B, Enum.A], '100011');

  enumSet.add(Enum.A);
  check(35, [Enum.F, Enum.B, Enum.A], '100011');

  enumSet.remove(Enum.C);
  check(35, [Enum.F, Enum.B, Enum.A], '100011');

  enumSet.remove(Enum.B);
  check(33, [Enum.F, Enum.A], '100001');

  enumSet.remove(Enum.A);
  check(32, [Enum.F], '100000');

  enumSet.clear();
  check(0, [], '0');

  enumSet.add(Enum.A);
  enumSet.add(Enum.B);
  enumSet.add(Enum.C);
  enumSet.add(Enum.D);
  enumSet.add(Enum.E);
  enumSet.add(Enum.F);
  check(63, [Enum.F, Enum.E, Enum.D, Enum.C, Enum.B, Enum.A], '111111');
}

void testConstructorsIntersects() {
  EnumSet<Enum> emptyA = new EnumSet<Enum>();
  EnumSet<Enum> emptyB = new EnumSet<Enum>.fromValue(0);
  EnumSet<Enum> emptyC = const EnumSet<Enum>.fixed(0);
  EnumSet<Enum> emptyD = new EnumSet<Enum>.fixed(0);


  void checkIntersects(EnumSet<Enum> a, EnumSet<Enum> b, bool expectedValue) {
    Expect.equals(expectedValue, a.intersects(b),
        "Unexpected intersects of $a and $b");
    Expect.equals(a.intersects(b), b.intersects(a),
        "Unsymmetric intersects of $a and $b");
  }

  void check(EnumSet<Enum> a, EnumSet<Enum> b) {
    Expect.equals(a.value, b.value,
        "Unexpected values of $a and $b");
    Expect.equals(a.hashCode, b.hashCode,
        "Unexpected hash codes of $a and $b");
    Expect.equals(a, b,
        "Unexpected equality of $a and $b");
    checkIntersects(a, b, !a.isEmpty);
  }

  check(emptyA, emptyA);
  check(emptyA, emptyB);
  check(emptyA, emptyC);
  check(emptyA, emptyD);

  EnumSet<Enum> singleA = new EnumSet<Enum>()..add(Enum.C);
  EnumSet<Enum> singleB = new EnumSet<Enum>.fromValue(4);
  EnumSet<Enum> singleC = const EnumSet<Enum>.fixed(4);
  EnumSet<Enum> singleD = new EnumSet<Enum>.fixed(4);
  EnumSet<Enum> singleE = new EnumSet<Enum>.fromValues([Enum.C]);
  EnumSet<Enum> singleF = new EnumSet<Enum>.fromValues([Enum.C], fixed: true);

  check(singleA, singleA);
  check(singleA, singleB);
  check(singleA, singleC);
  check(singleA, singleD);
  check(singleA, singleE);
  check(singleA, singleF);

  EnumSet<Enum> multiA = new EnumSet<Enum>()
      ..add(Enum.A)..add(Enum.D)..add(Enum.F);
  EnumSet<Enum> multiB = new EnumSet<Enum>.fromValue(41);
  EnumSet<Enum> multiC = const EnumSet<Enum>.fixed(41);
  EnumSet<Enum> multiD = new EnumSet<Enum>.fixed(41);
  EnumSet<Enum> multiE = new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.D]);
  EnumSet<Enum> multiF =
      new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.D], fixed: true);

  check(multiA, multiA);
  check(multiA, multiB);
  check(multiA, multiC);
  check(multiA, multiD);
  check(multiA, multiE);
  check(multiA, multiF);

  EnumSet<Enum> multi2 = new EnumSet<Enum>.fromValues([Enum.F, Enum.A, Enum.C]);

  checkIntersects(emptyA, singleA, false);
  checkIntersects(emptyA, multiA, false);
  checkIntersects(emptyA, multi2, false);

  checkIntersects(singleA, multiA, false);
  checkIntersects(singleA, multi2, true);

  checkIntersects(multiA, multi2, true);
}