// Copyright (c) 2019, 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.

// ignore_for_file: avoid_function_literals_in_foreach_calls

import 'dart:math' show Random;

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

import 'native_version_dummy.dart'
    if (dart.library.js) 'native_version_javascript.dart';

// Benchmark BigInt and Int64 formatting and parsing.

// Global sinks used to ensure that the results are not optimized.
dynamic sink1, sink2;

final bool runtimeFalse = int.parse('1') == 0;

// These benchmarks measure digit-throughput for parsing and formatting.
//
// Each benchmark targets processing [requiredDigits] decimal digits, spread
// over a list of input values. This makes the benchmarks for different integer
// lengths roughly comparable.  The number is chosen so that most benchmarks
// have very close to this number of digits. It corresponds to nine 4096-bit
// integers.
const requiredDigits = 11106;

class Benchmark extends BenchmarkBase {
  final List<String> strings;
  Benchmark(String name, int bits, {bool forInt = false})
    : strings = generateStrings(bits, forInt),
      super(name);

  static List<String> generateStrings(int bits, bool forInt) {
    final List<String> strings = [];
    final BigInt seed = (BigInt.one << bits) - BigInt.one;
    var b = seed;
    var restartDelta = BigInt.zero;
    var totalLength = 0;
    while (totalLength < requiredDigits) {
      if (b.bitLength < bits) {
        restartDelta += seed >> 20;
        restartDelta += BigInt.one;
        // Restart from a slightly reduced seed to generate different numbers.
        b = seed - restartDelta;
      }
      var string = b.toString();

      // Web integers lose precision due to rounding for larger values. Make
      // sure the string will round-trip correctly.
      if (forInt) string = int.parse(string).toString();

      strings.add(string);
      totalLength += string.length;
      var delta = b >> 8;
      if (delta == BigInt.zero) delta = BigInt.one;
      b = b - delta;
    }
    return strings;
  }
}

class ParseBigIntBenchmark extends Benchmark {
  ParseBigIntBenchmark(String name, int bits) : super(name, bits);

  @override
  void run() {
    for (final s in strings) {
      final b = BigInt.parse(s);
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

class ParseInt64Benchmark extends Benchmark {
  ParseInt64Benchmark(String name, int bits) : super(name, bits);

  @override
  void run() {
    for (final s in strings) {
      final b = Int64.parseInt(s);
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

class ParseIntBenchmark extends Benchmark {
  ParseIntBenchmark(String name, int bits) : super(name, bits, forInt: true);

  @override
  void run() {
    for (final s in strings) {
      final b = int.parse(s);
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

class ParseJsBigIntBenchmark extends Benchmark {
  ParseJsBigIntBenchmark(String name, int bits) : super(name, bits);

  @override
  void run() {
    for (final s in strings) {
      final b = nativeBigInt.parse(s);
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

class FormatBigIntBenchmark extends Benchmark {
  final List<BigInt> values = [];

  FormatBigIntBenchmark(String name, int bits) : super(name, bits);

  @override
  void setup() {
    for (String s in strings) {
      final BigInt b = BigInt.parse(s);
      values.add(b - BigInt.one); // We add 'one' back later.
    }
  }

  @override
  void run() {
    final one = BigInt.one;
    for (final b0 in values) {
      // Instances might cache `toString()`, so use arithmetic to create a new
      // instance to try to protect against measuring a cached string.
      final b = b0 + one;
      final s = b.toString();
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

class FormatIntBenchmark extends Benchmark {
  final List<int> values = [];

  FormatIntBenchmark(String name, int bits) : super(name, bits, forInt: true);

  @override
  void setup() {
    for (String s in strings) {
      final int b = int.parse(s);
      values.add(b - 4096); // We add this back later.
    }
  }

  @override
  void run() {
    for (final b0 in values) {
      // Instances might cache `toString()`, so use arithmetic to create a new
      // instance to try to protect against measuring a cached string.  We use
      // 4096 to avoid the arithmetic being a no-op due to rounding on web
      // integers (i.e. doubles).
      final b = b0 + 4096;
      final s = b.toString();
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

class FormatInt64Benchmark extends Benchmark {
  final List<Int64> values = [];

  FormatInt64Benchmark(String name, int bits) : super(name, bits);

  @override
  void setup() {
    for (String s in strings) {
      final b = Int64.parseInt(s);
      values.add(b - Int64.ONE); // We add this back later.
    }
  }

  @override
  void run() {
    final one = Int64.ONE;
    for (final b0 in values) {
      // Instances might cache `toString()`, so use arithmetic to create a new
      // instance to try to protect against measuring a cached string.
      final b = b0 + one;
      final s = b.toStringUnsigned();
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

class FormatJsBigIntBenchmark extends Benchmark {
  final List<Object> values = [];

  FormatJsBigIntBenchmark(String name, int bits) : super(name, bits);

  @override
  void setup() {
    final one = nativeBigInt.one;
    for (String s in strings) {
      final b = nativeBigInt.parse(s);
      values.add(nativeBigInt.subtract(b, one)); // We add this back later.
    }
  }

  @override
  void run() {
    final one = nativeBigInt.one;
    for (final b0 in values) {
      // Instances might cache `toString()`, so use arithmetic to create a new
      // instance to try to protect against measuring a cached string.
      final b = nativeBigInt.add(b0, one);
      final s = nativeBigInt.toStringMethod(b);
      sink1 = s;
      sink2 = b;
    }
    if (runtimeFalse) {
      print(sink1);
      print(sink2);
    }
  }
}

/// [DummyBenchmark] instantly returns a fixed 'slow' result.
class DummyBenchmark extends BenchmarkBase {
  DummyBenchmark(String name) : super(name);
  @override
  // A rate of one run per 2s, with a millisecond of noise.  Some variation is
  // needed for Golem's noise-based filtering and regression detection.
  double measure() => (2000 + Random().nextDouble() - 0.5) * 1000;
}

/// Create [ParseJsBigIntBenchmark], or a dummy benchmark if JavaScript BigInt
/// is not available.  This is to satisfy Golem's constraint that group
/// benchmarks always produce results for the same set of series.
BenchmarkBase Function() selectParseNativeBigIntBenchmark(
  String name,
  int bits,
) {
  return nativeBigInt.enabled
      ? () => ParseJsBigIntBenchmark(name, bits)
      : () => DummyBenchmark(name);
}

/// Create [FormatJsBigIntBenchmark], or a dummy benchmark if JavaScript BigInt
/// is not available.  This is to satisfy Golem's constraint that group
/// benchmarks always produce results for the same set of series.
BenchmarkBase Function() selectFormatNativeBigIntBenchmark(
  String name,
  int bits,
) {
  return nativeBigInt.enabled
      ? () => FormatJsBigIntBenchmark(name, bits)
      : () => DummyBenchmark(name);
}

void main() {
  final benchmarks = [
    () => ParseIntBenchmark('Int.parse.0009.bits', 9),
    () => ParseIntBenchmark('Int.parse.0032.bits', 32),
    // Use '63' bits to avoid 64-bit arithmetic overflowing to negative. Keep
    // the name as '64' to help comparisons.  The effect of an incorrect number
    // is reduced since benchmark results are normalized to a 'per digit' score
    () => ParseIntBenchmark('Int.parse.0064.bits', 63),
    () => ParseInt64Benchmark('Int64.parse.0009.bits', 9),
    () => ParseInt64Benchmark('Int64.parse.0032.bits', 32),
    () => ParseInt64Benchmark('Int64.parse.0064.bits', 64),
    () => ParseBigIntBenchmark('BigInt.parse.0009.bits', 9),
    () => ParseBigIntBenchmark('BigInt.parse.0032.bits', 32),
    () => ParseBigIntBenchmark('BigInt.parse.0064.bits', 64),
    () => ParseBigIntBenchmark('BigInt.parse.0256.bits', 256),
    () => ParseBigIntBenchmark('BigInt.parse.1024.bits', 1024),
    () => ParseBigIntBenchmark('BigInt.parse.4096.bits', 4096),
    selectParseNativeBigIntBenchmark('JsBigInt.parse.0009.bits', 9),
    selectParseNativeBigIntBenchmark('JsBigInt.parse.0032.bits', 32),
    selectParseNativeBigIntBenchmark('JsBigInt.parse.0064.bits', 64),
    selectParseNativeBigIntBenchmark('JsBigInt.parse.0256.bits', 256),
    selectParseNativeBigIntBenchmark('JsBigInt.parse.1024.bits', 1024),
    selectParseNativeBigIntBenchmark('JsBigInt.parse.4096.bits', 4096),
    () => FormatIntBenchmark('Int.toString.0009.bits', 9),
    () => FormatIntBenchmark('Int.toString.0032.bits', 32),
    () => FormatIntBenchmark('Int.toString.0064.bits', 63), // '63': See above.
    () => FormatInt64Benchmark('Int64.toString.0009.bits', 9),
    () => FormatInt64Benchmark('Int64.toString.0032.bits', 32),
    () => FormatInt64Benchmark('Int64.toString.0064.bits', 64),
    () => FormatBigIntBenchmark('BigInt.toString.0009.bits', 9),
    () => FormatBigIntBenchmark('BigInt.toString.0032.bits', 32),
    () => FormatBigIntBenchmark('BigInt.toString.0064.bits', 64),
    () => FormatBigIntBenchmark('BigInt.toString.0256.bits', 256),
    () => FormatBigIntBenchmark('BigInt.toString.1024.bits', 1024),
    () => FormatBigIntBenchmark('BigInt.toString.4096.bits', 4096),
    selectFormatNativeBigIntBenchmark('JsBigInt.toString.0009.bits', 9),
    selectFormatNativeBigIntBenchmark('JsBigInt.toString.0032.bits', 32),
    selectFormatNativeBigIntBenchmark('JsBigInt.toString.0064.bits', 64),
    selectFormatNativeBigIntBenchmark('JsBigInt.toString.0256.bits', 256),
    selectFormatNativeBigIntBenchmark('JsBigInt.toString.1024.bits', 1024),
    selectFormatNativeBigIntBenchmark('JsBigInt.toString.4096.bits', 4096),
  ];

  // Warm up all benchmarks to ensure consistent behavior of shared code.
  benchmarks.forEach(
    (bm) => bm()
      ..setup()
      ..run()
      ..run(),
  );

  benchmarks.forEach((bm) => bm().report());
}
