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

// Benchmark of efficiency of grapheme cluster operations.

import "package:characters/characters.dart";

import "../test/src/text_samples.dart";

double bench(int Function() action, int ms) {
  var elapsed = 0;
  var count = 0;
  var stopwatch = Stopwatch()..start();
  do {
    count += action();
    elapsed = stopwatch.elapsedMilliseconds;
  } while (elapsed < ms);
  return count / elapsed;
}

int iterateIndicesOnly() {
  var graphemeClusters = 0;
  var char = Characters(hangul).iterator;
  while (char.moveNext()) {
    graphemeClusters++;
  }
  char = Characters(genesis).iterator;
  while (char.moveNext()) {
    graphemeClusters++;
  }
  return graphemeClusters;
}

int iterateStrings() {
  var codeUnits = 0;
  var char = Characters(hangul).iterator;
  while (char.moveNext()) {
    codeUnits += char.current.length;
  }
  char = Characters(genesis).iterator;
  while (char.moveNext()) {
    codeUnits += char.current.length;
  }
  return codeUnits;
}

int reverseStrings() {
  var revHangul = reverse(hangul);
  var rev2Hangul = reverse(revHangul);
  if (hangul != rev2Hangul || hangul == revHangul) {
    throw AssertionError("Bad reverse");
  }
  var revGenesis = reverse(genesis);
  var rev2Genesis = reverse(revGenesis);
  if (genesis != rev2Genesis || genesis == revGenesis) {
    throw AssertionError("Bad reverse");
  }

  return (hangul.length + genesis.length) * 2;
}

int replaceStrings() {
  var count = 0;
  {
    const language = "한글";
    assert(language.length == 6);
    var chars = Characters(hangul);
    var replaced =
        chars.replaceAll(Characters(language), Characters("Hangul!"));
    count += replaced.string.length - hangul.length;
  }
  {
    var chars = Characters(genesis);
    var replaced = chars.replaceAll(Characters("And"), Characters("Also"));
    count += replaced.string.length - genesis.length;
  }
  return count;
}

String reverse(String input) {
  var chars = Characters(input);
  var buffer = StringBuffer();
  for (var it = chars.iteratorAtEnd; it.moveBack();) {
    buffer.write(it.current);
  }
  return buffer.toString();
}

void main(List<String> args) {
  var count = 1;
  if (args.isNotEmpty) count = int.tryParse(args[0]) ?? 1;

  // Warmup.
  bench(iterateIndicesOnly, 250);
  bench(iterateStrings, 250);
  bench(reverseStrings, 250);
  bench(replaceStrings, 250);

  var bestIterateIndices = 0.0;
  var bestIterateStrings = 0.0;
  var bestReverseStrings = 0.0;
  var bestReplaceStrings = 0.0;

  String toDigits(double d) {
    const n = 5;
    var s = d.round().toString();
    if (s.length >= n) return s;
    return d.toStringAsFixed(n - s.length);
  }

  for (var i = 0; i < count; i++) {
    var performance = bench(iterateIndicesOnly, 2000);
    print("Index Iteration: ${toDigits(performance)} gc/ms");
    if (performance > bestIterateIndices) bestIterateIndices = performance;

    performance = bench(iterateStrings, 2000);
    print("String Iteration: ${toDigits(performance)} cu/ms");
    if (performance > bestIterateStrings) bestIterateStrings = performance;

    performance = bench(reverseStrings, 2000);
    print("String Reversing: ${toDigits(performance)} cu/ms");
    if (performance > bestReverseStrings) bestReverseStrings = performance;

    performance = bench(replaceStrings, 2000);
    print("String Replacing: ${toDigits(performance)} changes/ms");
    if (performance > bestReplaceStrings) bestReplaceStrings = performance;
  }

  if (count > 1) {
    print("Best: ");
    print("Index Iteration: ${toDigits(bestIterateIndices)} gc/ms");
    print("String Iteration: ${toDigits(bestIterateStrings)} cu/ms");
    print("String Reversing: ${toDigits(bestReverseStrings)} cu/ms");
    print("String Replacing: ${toDigits(bestReplaceStrings)} changes/ms");
  }
}
