// Copyright (c) 2018, 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.

import "dart:math";
import "dart:typed_data";

import "package:expect/expect.dart";

main() {
  const nan = double.nan;
  const inf = double.infinity;

  int hash1234 = Object.hash(1, 2, 3, 4);
  Expect.type<int>(hash1234);
  Expect.equals(hash1234, Object.hash(1, 2, 3, 4)); // Consistent.
  Expect.equals(hash1234, Object.hashAll([1, 2, 3, 4]));
  Expect.equals(hash1234, Object.hashAll(Uint8List.fromList([1, 2, 3, 4])));

  Expect.notEquals(hash1234, Object.hash(1, 2, 3, 4, null));

  Expect.equals(Object.hash(1, 2, 3, 4, 5, 6, 7, 8, 9),
      Object.hashAll([1, 2, 3, 4, 5, 6, 7, 8, 9]));

  // Check that we can call `hash` with 2-20 arguments,
  // and they all agree with `hashAll`.
  var random = Random();
  for (var i = 2; i <= 20; i++) {
    var arguments = [for (var j = 0; j < i; j++) random.nextInt(256)];
    var hashAll = Object.hashAll(arguments);
    var hash = Function.apply(Object.hash, arguments);
    Expect.equals(
        hashAll,
        hash,
        "hashAll and hash disagrees for $i values:\n"
        "$arguments");
  }

  // Works for all kinds of objects;
  int varHash = Object.hash(
      "string", 3, nan, true, null, Type, #Symbol, const Object(), function);
  Expect.equals(
      varHash,
      Object.hashAll([
        "string",
        3,
        nan,
        true,
        null,
        Type,
        #Symbol,
        const Object(),
        function
      ]));

  // Object doesn't matter, just its hash code.
  Expect.equals(hash1234,
      Object.hash(Hashable(1), Hashable(2), Hashable(3), Hashable(4)));

  // It's potentially possible to get a conflict, but it doesn't happen here.
  Expect.notEquals("str".hashCode, Object.hashAll(["str"]));

  var hash12345 = Object.hashAllUnordered([1, 2, 3, 4, 5]);
  for (var p in permutations([1, 2, 3, 4, 5])) {
    Expect.equals(hash12345, Object.hashAllUnordered(p));
  }
  Expect.notEquals(
      Object.hashAllUnordered(["a", "a"]), Object.hashAllUnordered(["a"]));

  Expect.notEquals(Object.hashAllUnordered(["a", "a"]),
      Object.hashAllUnordered(["a", "a", "a", "a"]));

  Expect.notEquals(Object.hashAllUnordered(["a", "b"]),
      Object.hashAllUnordered(["a", "a", "a", "b"]));

  /// Unordered hashing works for all kinds of objects.
  var unorderHash = Object.hashAllUnordered([
    "string",
    3,
    nan,
    true,
    null,
    Type,
    #Symbol,
    const Object(),
    function,
  ]);

  var unorderHash2 = Object.hashAllUnordered([
    true,
    const Object(),
    3,
    function,
    Type,
    "string",
    null,
    nan,
    #Symbol,
  ]);
  Expect.equals(unorderHash, unorderHash2);
}

/// Lazily emits all permutations of [values].
///
/// Modifies [values] rather than create a new list.
/// The [values] list is guaranteed to end up in its original state
/// after all permutations have been read.
Iterable<List<T>> permutations<T>(List<T> values) {
  Iterable<List<T>> recPermute(int end) sync* {
    if (end == 1) {
      yield values;
      return;
    }
    for (var i = 0; i < end; i++) {
      yield* recPermute(end - 1);
      // Rotate values[i:].
      var tmp = values.first;
      for (var k = 1; k < end; k++) values[k - 1] = values[k];
      values[end - 1] = tmp;
    }
  }

  return recPermute(values.length);
}

// static function, used as constant value.
void function() {}

class Hashable {
  final Object o;
  Hashable(this.o);
  bool operator ==(Object other) => other is Hashable && o == other.o;
  int get hashCode => o.hashCode;
}
