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

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;
  late List<Uint8List> chunks;
  int totalInputSize = 0;
  int totalOutputSize = 0;

  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) as Uint8List;
    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
  void warmup() {
    BenchmarkBase.measureFor(run, 1000);
  }

  @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.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();
  }
}
