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

// @dart=2.9

import 'dart:convert';
import 'dart:typed_data';

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 Utf8Decode extends BenchmarkBase {
  final String language;
  final String text;
  final int size;
  final bool allowMalformed;
  List<Uint8List> chunks;
  int totalInputSize;
  int totalOutputSize;

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

  Utf8Decode(this.language, this.text, this.size, this.allowMalformed)
      : super(_makeName(language, size, allowMalformed));

  @override
  void setup() {
    final Uint8List data = utf8.encode(text);
    if (data.length != 10000) {
      throw 'Expected input data of exactly 10000 bytes.';
    }
    if (size < data.length) {
      // Split into chunks.
      chunks = <Uint8List>[];
      int startPos = 0;
      for (int pos = size; pos < data.length; pos += size) {
        int endPos = pos;
        while ((data[endPos] & 0xc0) == 0x80) {
          endPos--;
        }
        chunks.add(Uint8List.fromList(data.sublist(startPos, endPos)));
        startPos = endPos;
      }
      chunks.add(Uint8List.fromList(data.sublist(startPos, data.length)));
      totalInputSize = data.length;
      totalOutputSize = text.length;
    } else if (size > data.length) {
      // Repeat data to the desired length.
      final Uint8List expanded = Uint8List(size);
      for (int i = 0; i < size; i++) {
        expanded[i] = data[i % data.length];
      }
      chunks = <Uint8List>[expanded];
      totalInputSize = size;
      totalOutputSize = text.length * size ~/ data.length;
    } else {
      // Use data as is.
      chunks = <Uint8List>[data];
      totalInputSize = data.length;
      totalOutputSize = text.length;
    }
  }

  @override
  void run() {
    int lengthSum = 0;
    for (int i = 0; i < chunks.length; i++) {
      final String s = utf8.decode(chunks[i], allowMalformed: allowMalformed);
      lengthSum += s.length;
    }
    if (lengthSum != totalOutputSize) {
      throw 'Output length doesn\'t match expected.';
    }
  }

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

  @override
  double measure() {
    // Report time per input byte.
    return super.measure() / totalInputSize;
  }

  @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 bool testMalformed =
      args != null && args.isNotEmpty && args.first == 'malformed';
  final benchmarks = [
    // Only benchmark with allowMalformed: false unless specified otherwise.
    for (bool allowMalformed in [false, if (testMalformed) true])
      for (int size in [10, 10000, 10000000])
        for (String language in texts.keys)
          () => Utf8Decode(language, texts[language], size, allowMalformed)
  ];

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