// Copyright (c) 2020, 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 for UTF-8 encoding

import 'dart:convert';

import 'package:benchmark_harness/benchmark_harness.dart';

import 'datext_latin1_10k.dart';
import 'entext_ascii_10k.dart';
import 'netext_3_10k.dart';
import 'rutext_2_10k.dart';
import 'sktext_10k.dart';
import 'zhtext_10k.dart';

class Utf8Encode extends BenchmarkBase {
  final String language;
  final String originalText;
  // Size is measured in number of runes rather than number of bytes.
  // This differs from the Utf8Decode benchmark, but runes are the input
  // to the encode function which makes them more natural than bytes here.
  final int size;
  List<String> benchmarkTextChunks = List.empty(growable: true);

  static String _makeName(String language, int size) {
    String name = 'Utf8Encode.$language.';
    name += size >= 1000000
        ? '${size ~/ 1000000}M'
        : size >= 1000
        ? '${size ~/ 1000}k'
        : '$size';
    return name;
  }

  Utf8Encode(this.language, this.originalText, this.size)
    : super(_makeName(language, size));

  @override
  void setup() {
    final int nRunes = originalText.runes.toList().length;
    final String repeatedText = originalText * (size / nRunes).ceil();
    final List<int> runes = repeatedText.runes.toList();
    final int nChunks = (size < nRunes) ? (nRunes / size).floor() : 1;
    for (int i = 0; i < nChunks; i++) {
      final offset = i * size;
      benchmarkTextChunks.add(
        String.fromCharCodes(runes.sublist(offset, offset + size)),
      );
    }
  }

  @override
  void run() {
    for (int i = 0; i < benchmarkTextChunks.length; i++) {
      final encoded = utf8.encode(benchmarkTextChunks[i]);
      if (encoded.length < benchmarkTextChunks[i].length) {
        throw 'There should be at least as many encoded bytes as runes';
      }
    }
  }

  @override
  void exercise() {
    // Only a single run per measurement.
    run();
  }

  @override
  double measure() {
    // Report time per input rune.
    return super.measure() / size / benchmarkTextChunks.length;
  }

  @override
  void report() {
    // Report time in nanoseconds.
    final double score = measure() * 1000.0;
    print('$name(RunTime): $score ns.');
  }
}

void main(List<String> args) {
  const texts = {'en': en, 'da': da, 'sk': sk, 'ru': ru, 'ne': ne, 'zh': zh};
  final benchmarks = [
    for (int size in [10, 10000, 10000000])
      for (String language in texts.keys)
        () => Utf8Encode(language, texts[language]!, size),
  ];

  for (var bm in benchmarks) {
    bm().report();
  }
}
