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

import 'dart:collection';
import 'dart:typed_data';

import 'package:benchmark_harness/benchmark_harness.dart';
import 'sound_splay_tree.dart';

List<int> sieve(List<int> initialCandidates) {
  final candidates = SplayTreeSet<int>.from(initialCandidates);
  final int last = candidates.last;
  final primes = <int>[];
  // ignore: literal_only_boolean_expressions
  while (true) {
    final int prime = candidates.first;
    if (prime * prime > last) break;
    primes.add(prime);
    for (int i = prime; i <= last; i += prime) {
      candidates.remove(i);
    }
  }
  return primes..addAll(candidates);
}

List<int> sieveSound(List<int> initialCandidates) {
  final candidates = SoundSplayTreeSet<int>.from(initialCandidates);
  final int last = candidates.last;
  final primes = <int>[];
  // ignore: literal_only_boolean_expressions
  while (true) {
    final int prime = candidates.first;
    if (prime * prime > last) break;
    primes.add(prime);
    for (int i = prime; i <= last; i += prime) {
      candidates.remove(i);
    }
  }
  return primes..addAll(candidates);
}

/// Returns a list of integers from [first] to [last], both inclusive.
List<int> range(int first, int last) {
  return List<int>.generate(last - first + 1, (int i) => i + first);
}

int id(int x) => x;
int add1(int i) => 1 + i;
bool isEven(int i) => i.isEven;
void exercise(Iterable<int> hello) {
  if (hello.toList().length != 5) throw 'x1';
  if (List.from(hello).length != 5) throw 'x1';
  if (Set.from(hello).length != 4) throw 'x1';
  if (List<int>.from(hello).where(isEven).length != 3) throw 'x1';
  if (hello.where(isEven).length != 3) throw 'x1';
  if (hello.map(add1).where(isEven).length != 2) throw 'x1';
  if (hello.where(isEven).map(add1).length != 3) throw 'x1';
}

void busyWork() {
  // A lot of busy-work calling map/where/toList/List.from to ensure the core
  // library is used with some degree of polymorphism.
  final L1 = 'hello'.codeUnits;
  final L2 = Uint16List(5)..setRange(0, 5, L1);
  final L3 = Uint32List(5)..setRange(0, 5, L1);
  exercise(L1);
  exercise(L2);
  exercise(L3);
  exercise(UnmodifiableListView<int>(L1));
  exercise(UnmodifiableListView<int>(L2));
  exercise(UnmodifiableListView<int>(L3));
  exercise(L1.asMap().values);
  exercise(L1.toList().asMap().values);
  final M1 =
      Map<String, int>.fromIterables(<String>['a', 'b', 'c', 'd', 'e'], L1);
  final M2 = const <String, int>{
    'a': 104,
    'b': 101,
    'c': 108,
    'd': 108,
    'e': 111
  };
  exercise(M1.values);
  exercise(M2.values);
}

main() {
  final benchmarks = [
    Base(sieve, 'CollectionSieves-SplayTreeSet-removeLoop'),
    Base(sieveSound, 'CollectionSieves-SoundSplayTreeSet-removeLoop'),
  ];
  for (int i = 0; i < 10; i++) {
    busyWork();
    for (var bm in benchmarks) {
      bm.run();
    }
  }
  for (var bm in benchmarks) {
    bm.report();
  }
}

class Base extends BenchmarkBase {
  final algorithm;
  Base(this.algorithm, String name) : super(name);
  static final input = range(2, 5000);
  void run() {
    final primes = algorithm(input);
    if (primes.length != 669) throw 'Wrong result for $name: ${primes.length}';
  }
}
