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

// Test that the secure random generator does not systematically generates
// duplicates. Note that this test is flaky by definition, since duplicates
// can occur. They should be extremely rare, though.

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

main() {
  var results;
  var rng0;
  var rng1;
  var checkInt = (max) {
    var intVal0 = rng0.nextInt(max);
    var intVal1 = rng1.nextInt(max);
    if (max > (1 << 28)) {
      Expect.isFalse(results.contains(intVal0));
      results.add(intVal0);
      Expect.isFalse(results.contains(intVal1));
      results.add(intVal1);
    }
  };
  results = [];
  rng0 = new Random.secure();
  for (var i = 0; i <= 32; i++) {
    rng1 = new Random.secure();
    checkInt(pow(2, 32));
    checkInt(pow(2, 32 - i));
    checkInt(1000000000);
  }
  var checkDouble = () {
    var doubleVal0 = rng0.nextDouble();
    var doubleVal1 = rng1.nextDouble();
    Expect.isFalse(results.contains(doubleVal0));
    results.add(doubleVal0);
    Expect.isFalse(results.contains(doubleVal1));
    results.add(doubleVal1);
  };
  results = [];
  rng0 = new Random.secure();
  for (var i = 0; i < 32; i++) {
    rng1 = new Random.secure();
    checkDouble();
  }
  var cnt0 = 0;
  var cnt1 = 0;
  rng0 = new Random.secure();
  for (var i = 0; i < 32; i++) {
    rng1 = new Random.secure();
    cnt0 += rng0.nextBool() ? 1 : 0;
    cnt1 += rng1.nextBool() ? 1 : 0;
  }
  Expect.isTrue((cnt0 > 0) && (cnt0 < 32));
  Expect.isTrue((cnt1 > 0) && (cnt1 < 32));
}
