// 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) {
  int elapsed = 0;
  int count = 0;
  var stopwatch = Stopwatch()..start();
  do {
    count += action();
    elapsed = stopwatch.elapsedMilliseconds;
  } while (elapsed < ms);
  return count / elapsed;
}

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

int iterateStrings() {
  int 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 "Bad reverse";

  var revGenesis = reverse(genesis);
  var rev2Genesis = reverse(revGenesis);
  if (genesis != rev2Genesis || genesis == revGenesis) throw "Bad reverse";

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

int replaceStrings() {
  int 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) {
  int count = 1;
  if (args.isNotEmpty) count = int.tryParse(args[0]) ?? 1;

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

  for (int i = 0; i < count; i++) {
    var performance = bench(iterateIndicesOnly, 2000);
    print("Index Iteration: $performance gc/ms");
    performance = bench(iterateStrings, 2000);
    print("String Iteration: $performance cu/ms");
    performance = bench(reverseStrings, 2000);
    print("String Reversing: $performance cu/ms");
    performance = bench(replaceStrings, 2000);
    print("String Replacing: $performance changes/ms");
  }
}
