// 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.

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);
}

void 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);
  @override
  void run() {
    final primes = algorithm(input);
    if (primes.length != 669) throw 'Wrong result for $name: ${primes.length}';
  }
}
