// Copyright (c) 2023, 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, complex cases.
///
/// This benckmark complements the `Utf8Decode` benchmarks by exploring
/// different scenarios. There are three axes of variation - input complexity,
/// conversion type, and polymorphism. The variantions are represented in the
/// benchmark name, roughly
///
///     Utf8DecodeComplex.<polymorphism>.<conversion>.<data>.<complexity>.10k
///
/// ### Complexity
///
/// The input complexity is explored by having input sequences that are the
/// UTF-8 encoding of (1) ASCII strings ('ascii'), (2) strings that can be
/// represented by one-byte strings ('1byte'), and (3) strings need to be
/// represented by two-byte strings ('2byte').
///
/// Both of of these benchmarks process 10k bytes of input:
///
///     Utf8DecodeComplex.mono.simple.ascii.10k
///     Utf8DecodeComplex.mono.simple.2byte.10k
///
/// The first has ascii bytes as input, the simplest case. The second requires
/// parsing the variable-length UTF-8 code points.
///
/// ### Conversion
///
/// The conversion variations are 'simple', for a one-shot conversion of a List
/// of bytes to a string, and 'chunked' for a conversion that uses the chunked
/// conversion API to process the 10k bytes in chunks of a few hundred
/// bytes. This exercises different paths through the decoder. We would expect
/// the chuncked version to be slower, but only by a few percent.
///
/// ### Data
///
/// The type of the input is part of the benchmark name. When the input is a
/// modifiable `Unit8List`, there is no `.<data>` part to the name. Otherwise:
///
///     .list  - Input is a system List (`List.of`)
///     .unmodifiable - Input is an ummodifiable `Uint8List`.
///
/// ### Polymorphism
///
/// Polymorphism is explored by compiling several programs that run different
/// subsets of the benchmarks.
///
/// Whole-program optimizing compilers like AOT or dart2js can sometimes 'see'
/// that the conversion code is called with a single implementation of List and
/// optimize the code accordingly. This can produce faster code, but might be
/// too optimistic as prediction of real-world performance.
///
/// These two benchmarks run the same code, on a `Uint8List` containing the same
/// values. Other than the name, the benchmarks are identical:
///
///     Utf8DecodeComplex.mono.simple.ascii.10k
///     Utf8DecodeComplex.poly.simple.ascii.10k
///
/// The difference is that the 'mono' benchmark is part of a program that passes
/// only modifiable `Uint8List` lists to `utf8.decode`, whereas the 'poly'
/// benchmark is part of a program that passes several different List
/// implementation type to `utf8.decode`, including system lists (`List.of`) and
/// and unmodifiable Uint8Lists.
///
/// There are three monomorphic entry points which are called from the `main`
/// method of an otherwise trivial program - `mainMono1`, `mainMono2` and
/// `mainMono3`.  `mainMono1` does conversions exclusively on the preferred data
/// type, `Uint8List`.  `mainMono2` does conversions exclusively on the system
/// list type (`List.of`). `mainMono3` does conversions exclusively on
/// unmodifiable `Uint8List`.
///
/// The primary program calls the `mainPoly` entry point.
///
/// Benchmark results from the different programs can be collected into a single
/// suite.
library;

import 'dart:convert';
import 'dart:math' show min;
import 'dart:typed_data';

import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:expect/expect.dart';

// ASCII values which are start the sequence for quick validation that
// conversion happened.
const bytes0tag = 0x30;
const bytes1tag = 0x31;
const bytes2tag = 0x32;

// Input which decodes to a string where all code units are 7-bit ASCII.
const bytes0 = [
  bytes0tag, //    0, U+0030
  0x48, 0x45, 0x4C, 0x4C, 0x4f, 0x0A, // "HELLO\n"
];

// Input which decodes to a string where all code units fit in 1 byte.
const bytes1 = [
  bytes1tag, //    1, U+0031
  0x41, //         A, U+0040
  0xC2, 0xB1, //   ±, U+00B1
  0xC3, 0xB7, //   ÷, U+00F7
  0x0A, //         \n, U+000A
];

// Input which decodes to a string where some code units require 2 bytes.
const bytes2 = [
  bytes2tag, //              2, U+0032
  0x41, //                   A, U+0040
  0xC2, 0xB1, //             ±, U+00B1
  0xC3, 0xB7, //             ÷, U+00F7
  0xC4, 0x90, //             Đ, U+0111
  0xE0, 0xA6, 0x86, //       আ, U+0986
  0xF0, 0x9F, 0x87, 0xB9, // 🇹, U+1F1F9
  0xF0, 0x9F, 0x87, 0xBB, // 🇻, U+1F1FB  🇹🇻
];

const targetSize = 10000;
const chunkSize = 250;

void check(String result, List<int> sequence) {
  // Each sequence starts with a different ASCII value so we can quickly 'look
  // up' the expected length of the decoded expanded sequence.
  final expectedLength = switch (sequence[0]) {
    bytes0tag => targetSize,
    bytes1tag => 7144,
    bytes2tag => 5266,
    _ => throw 'Unexpected sequence start: ${sequence[0]}',
  };
  Expect.equals(expectedLength, result.length);
}

/// Expands a sequence by repetition and padding to `targetSize` bytes.
Uint8List makeSequence(List<int> bytes) {
  Expect.equals(
    1,
    bytes.length.gcd(chunkSize),
    'Bad repeated size (${bytes.length}).'
    ' Repeated sequence should be co-prime with chunk size ($chunkSize)'
    ' to exercise more UTF-8 boundaries',
  );
  final repeats = List.filled(
    targetSize ~/ bytes.length,
    bytes,
  ).expand((byte) => byte);
  final padding = List.filled(targetSize.remainder(bytes.length), 0); // NULs.
  final sequence = Uint8List.fromList([...repeats, ...padding]);
  Expect.equals(targetSize, sequence.length);
  return sequence;
}

final Uint8List sequence0 = makeSequence(bytes0);
final Uint8List sequence1 = makeSequence(bytes1);
final Uint8List sequence2 = makeSequence(bytes2);

class Utf8DecodeBenchmarkBase extends BenchmarkBase {
  Utf8DecodeBenchmarkBase(String name) : super('Utf8DecodeComplex.$name');

  late int totalInputSize;

  @override
  void exercise() {
    // Only a single run per measurement instead of the usual 10.
    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.');
  }
}

class Simple extends Utf8DecodeBenchmarkBase {
  final List<int> sequence;
  Simple(super.name, this.sequence) {
    totalInputSize = sequence.length;
  }

  @override
  void run() {
    final result = utf8.decode(sequence);
    check(result, sequence);
  }
}

abstract class ChunkedBase extends Utf8DecodeBenchmarkBase {
  final List<int> sequence;
  late List<List<int>> chunks;
  ChunkedBase(super.name, this.sequence);

  List<int> slice(List<int> list, int start, int end);

  @override
  void setup() {
    totalInputSize = sequence.length;
    chunks = [];
    for (int i = 0; i < totalInputSize; i += chunkSize) {
      final chunk = slice(sequence, i, min(i + chunkSize, totalInputSize));
      chunks.add(chunk);
    }
  }

  @override
  void run() {
    late final String result;
    final byteSink = const Utf8Decoder().startChunkedConversion(
      StringConversionSink.withCallback((s) => result = s),
    );

    for (final chunk in chunks) {
      byteSink.add(chunk);
    }
    byteSink.close();
    check(result, sequence);
  }
}

class Chunked extends ChunkedBase {
  Chunked(super.name, super.sequence);

  @override
  List<int> slice(List<int> list, int start, int end) {
    return list.sublist(start, end);
  }
}

class ChunkedUnmodifiable extends ChunkedBase {
  ChunkedUnmodifiable(super.name, Uint8List super.sequence);

  @override
  Uint8List slice(List<int> list, int start, int end) {
    return Uint8List.fromList(list.sublist(start, end)).asUnmodifiableView();
  }
}

void runAll(List<BenchmarkBase> benchmarks) {
  // Warm up all the benchmarks to avoid overly optimistic results for the first
  // few benchmarks due to temporary monomorphism in JIT compilers.
  for (var bm in benchmarks) {
    bm.setup();
    bm.warmup();
  }

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

void mainPoly() {
  // Polymorphic: Inputs of several types.
  final benchmarks = [
    Simple('poly.simple.ascii.10k', sequence0),
    Simple('poly.simple.1byte.10k', sequence1),
    Simple('poly.simple.2byte.10k', sequence2),
    Simple('poly.simple.list.ascii.10k', List.of(sequence0)),
    Simple('poly.simple.list.1byte.10k', List.of(sequence1)),
    Simple('poly.simple.list.2byte.10k', List.of(sequence2)),
    Simple(
      'poly.simple.unmodifiable.ascii.10k',
      sequence0.asUnmodifiableView(),
    ),
    Simple(
      'poly.simple.unmodifiable.1byte.10k',
      sequence1.asUnmodifiableView(),
    ),
    Simple(
      'poly.simple.unmodifiable.2byte.10k',
      sequence2.asUnmodifiableView(),
    ),
    Chunked('poly.chunked.ascii.10k', sequence0),
    Chunked('poly.chunked.1byte.10k', sequence1),
    Chunked('poly.chunked.2byte.10k', sequence2),
    Chunked('poly.chunked.list.ascii.10k', List.of(sequence0)),
    Chunked('poly.chunked.list.1byte.10k', List.of(sequence1)),
    Chunked('poly.chunked.list.2byte.10k', List.of(sequence2)),
    ChunkedUnmodifiable(
      'poly.chunked.unmodifiable.ascii.10k',
      sequence0.asUnmodifiableView(),
    ),
    ChunkedUnmodifiable(
      'poly.chunked.unmodifiable.1byte.10k',
      sequence1.asUnmodifiableView(),
    ),
    ChunkedUnmodifiable(
      'poly.chunked.unmodifiable.2byte.10k',
      sequence2.asUnmodifiableView(),
    ),
  ];
  runAll(benchmarks);
}

void mainMono1() {
  // Monomorphic: All inputs are `Uint8List`s.
  final benchmarks = [
    Simple('mono.simple.ascii.10k', sequence0),
    Simple('mono.simple.1byte.10k', sequence1),
    Simple('mono.simple.2byte.10k', sequence2),
    Chunked('mono.chunked.ascii.10k', sequence0),
    Chunked('mono.chunked.1byte.10k', sequence1),
    Chunked('mono.chunked.2byte.10k', sequence2),
  ];
  runAll(benchmarks);
}

void mainMono2() {
  // Monomorphic: All inputs are ordinary (system) Lists.
  final benchmarks = [
    Simple('mono.simple.list.ascii.10k', List.of(sequence0)),
    Simple('mono.simple.list.1byte.10k', List.of(sequence1)),
    Simple('mono.simple.list.2byte.10k', List.of(sequence2)),
    Chunked('mono.chunked.list.ascii.10k', List.of(sequence0)),
    Chunked('mono.chunked.list.1byte.10k', List.of(sequence1)),
    Chunked('mono.chunked.list.2byte.10k', List.of(sequence2)),
  ];
  runAll(benchmarks);
}

void mainMono3() {
  // Monomorphic: All inputs are unmodifiable `Uint8List`s.
  final benchmarks = [
    Simple(
      'mono.simple.unmodifiable.ascii.10k',
      sequence0.asUnmodifiableView(),
    ),
    Simple(
      'mono.simple.unmodifiable.1byte.10k',
      sequence1.asUnmodifiableView(),
    ),
    Simple(
      'mono.simple.unmodifiable.2byte.10k',
      sequence2.asUnmodifiableView(),
    ),
    ChunkedUnmodifiable(
      'mono.chunked.unmodifiable.ascii.10k',
      sequence0.asUnmodifiableView(),
    ),
    ChunkedUnmodifiable(
      'mono.chunked.unmodifiable.1byte.10k',
      sequence1.asUnmodifiableView(),
    ),
    ChunkedUnmodifiable(
      'mono.chunked.unmodifiable.2byte.10k',
      sequence2.asUnmodifiableView(),
    ),
  ];
  runAll(benchmarks);
}
