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

// @dart=2.9

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;

  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;
    benchmarkTextChunks = List<String>.filled(nChunks, null);
    for (int i = 0; i < nChunks; i++) {
      final offset = i * size;
      benchmarkTextChunks[i] = 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();
  }
}
