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

import 'dart:collection';

import 'package:benchmark_harness/benchmark_harness.dart';

// Benchmark for polymorphic map copying.
//
// The set of benchmarks compares the cost of copying default Maps
// (LinkedHashMaps) and HashMaps, for small and large maps.
//
// The maps have a key type `Object?`, since we want to use Strings, ints and
// user-defined types.  The class `Thing` is a used-defined type with an
// inexpensive hashCode operation. String keys are interesting because they are
// quite common, and are special-cased in the JavaScript runtime.
//
// Benchmarks have names following this pattern:
//
//     MapCopy.{Map,HashMap}.{String,Thing}.of.{Map,HashMap}.{N}
//     MapCopy.{Map,HashMap}.{String,Thing}.copyOf.{Map,HashMap}.{N}
//     MapCopy.{Map,HashMap}.{String,Thing}.fromEntries.{Map,HashMap}.{N}
//
// For example, MapCopy.Map.String.of.HashMap.2 would call
//
//     Map<Object, Object>.of(m)
//
// where `m` is a `HashMap<String, Object>` with 2 entries.
//
// The `copyOf` variant creates an empty map and populates it using `forEach`,
// so MapCopy.HashMap.Thing.copyOf.HashMap.100 would call:
//
//    HashMap<Object, Object> result = HashMap();
//    m.forEach((key, value) { result[key] = value; });
//
// where `m` is a `HashMap<Thing, Object>` with 100 entries.
//
// The `fromEntries` variant creates a map via `Map.fromEntries(other.entries)`.
//
// Benchmarks are run for small maps (e.g. 2 entries, names ending in `.2`) and
// 'large' maps (100 entries or `.100`). The benchmarks are normalized on the
// number of elements to make benchmarks with different input sizes more
// comparable.

abstract class Benchmark<K> extends BenchmarkBase {
  final String targetKind; // 'Map' or 'HashMap'.
  late final String keyKind = _keyKind(K); // 'String' or 'Thing' or 'int'.
  final String methodKind; // 'of' or 'copyOf' or 'fromEntries'.
  final String sourceKind; // 'Map' or 'HashMap'.
  final int length;
  final List<Map<Object?, Object>> inputs = [];

  Benchmark(this.targetKind, this.methodKind, this.sourceKind, this.length)
    : super(
        'MapCopy.$targetKind.${_keyKind(K)}.$methodKind.$sourceKind'
        '.$length',
      );

  static String _keyKind(Type type) {
    if (type == String) return 'String';
    if (type == int) return 'int';
    if (type == Thing) return 'Thing';
    throw UnsupportedError('Unsupported type $type');
  }

  /// Override this method with one that will copy [input] to [output].
  void copy();

  @override
  void setup() {
    // Ensure setup() is idempotent.
    if (inputs.isNotEmpty) return;

    const totalEntries = 1000;

    int totalLength = 0;
    while (totalLength < totalEntries) {
      final sample = makeSample();
      inputs.add(sample);
      totalLength += sample.length;
    }

    // Sanity checks.
    for (var sample in inputs) {
      if (sample.length != length) throw 'Wrong length: $length $sample';
    }
    if (totalLength != totalEntries) {
      throw 'totalLength $totalLength != expected $totalEntries';
    }
  }

  int _sequence = 0;

  Map<Object?, Object> makeSample() {
    late final Map<K, Object> sample;
    if (sourceKind == 'Map') sample = {};
    if (sourceKind == 'HashMap') sample = HashMap();
    for (int i = 1; i <= length; i++) {
      _sequence = (_sequence + 119) & 0x1ffffff;
      final K key = makeKey(_sequence);
      sample[key] = i;
    }
    return sample;
  }

  K makeKey(int i) {
    if (keyKind == 'String') return 'key-$i' as K;
    if (keyKind == 'int') return i as K;
    if (keyKind == 'Thing') return Thing() as K;
    throw UnsupportedError('Unsupported type $K');
  }

  @override
  void run() {
    for (var sample in inputs) {
      input = sample;
      copy();
    }
    if (output.length != inputs.first.length) throw 'Bad result: $output';
  }
}

class Thing {
  static int _counter = 0;
  final int _index;
  Thing() : _index = ++_counter;

  @override
  bool operator ==(Object other) => other is Thing && _index == other._index;

  @override
  int get hashCode => _index;
}

// All the 'copy' methods use [input] and [output] rather than a parameter and
// return value to avoid the possibility of a parametric covariance type check
// in the call sequence.
Map<Object?, Object> input = {};
var output;

class BaselineBenchmark extends Benchmark<String> {
  BaselineBenchmark(int length) : super('Map', 'baseline', 'Map', length);

  @override
  void copy() {
    // Dummy 'copy' to measure overhead of benchmarking loops.
    output = input;
  }
}

class MapOfBenchmark<K> extends Benchmark<K> {
  MapOfBenchmark(String sourceKind, int length)
    : super('Map', 'of', sourceKind, length);

  @override
  void copy() {
    output = Map<Object?, Object>.of(input);
  }
}

class HashMapOfBenchmark<K> extends Benchmark<K> {
  HashMapOfBenchmark(String sourceKind, int length)
    : super('HashMap', 'of', sourceKind, length);

  @override
  void copy() {
    output = HashMap<Object?, Object>.of(input);
  }
}

class MapCopyOfBenchmark<K> extends Benchmark<K> {
  MapCopyOfBenchmark(String sourceKind, int length)
    : super('Map', 'copyOf', sourceKind, length);

  @override
  void copy() {
    final map = <Object?, Object>{};
    input.forEach((k, v) {
      map[k] = v;
    });
    output = map;
  }
}

class HashMapCopyOfBenchmark<K> extends Benchmark<K> {
  HashMapCopyOfBenchmark(String sourceKind, int length)
    : super('HashMap', 'copyOf', sourceKind, length);

  @override
  void copy() {
    final map = HashMap<Object?, Object>();
    input.forEach((k, v) {
      map[k] = v;
    });
    output = map;
  }
}

class MapFromEntriesBenchmark<K> extends Benchmark<K> {
  MapFromEntriesBenchmark(String sourceKind, int length)
    : super('Map', 'fromEntries', sourceKind, length);

  @override
  void copy() {
    output = Map<Object?, Object>.fromEntries(input.entries);
  }
}

class HashMapFromEntriesBenchmark<K> extends Benchmark<K> {
  HashMapFromEntriesBenchmark(String sourceKind, int length)
    : super('HashMap', 'fromEntries', sourceKind, length);

  @override
  void copy() {
    output = HashMap<Object?, Object>.fromEntries(input.entries);
  }
}

/// Use the common methods for many different kinds of Map to make the calls in
/// the runtime implementation polymorphic.
void pollute() {
  final Map<String, Object> m1 = Map.of({'hello': 66});
  final Map<String, Object> m2 = HashMap.of(m1);
  final Map<int, Object> m3 = Map.of({1: 66});
  final Map<int, Object> m4 = HashMap.of({1: 66});
  final Map<Object, Object> m5 =
      Map.identity()
        ..[Thing()] = 1
        ..[Thing()] = 2;
  final Map<Object, Object> m6 =
      HashMap.identity()
        ..[Thing()] = 1
        ..[Thing()] = 2;
  final Map<Object, Object> m7 = UnmodifiableMapView(m1);
  final Map<Object, Object> m8 = UnmodifiableMapView(m2);
  final Map<Object, Object> m9 = UnmodifiableMapView(m3);
  final Map<Object, Object> m10 = UnmodifiableMapView(m4);

  int c = 0;
  for (final m in [m1, m2, m3, m4, m5, m6, m7, m8, m9, m10]) {
    final Map<Object, Object> d1 = Map.of(m);
    final Map<Object, Object> d2 = HashMap.of(m);
    // ignore: prefer_collection_literals
    final Map<Object, Object> d3 = Map()..addAll(m);
    final Map<Object, Object> d4 = {...m, ...m};
    final Map<Object, Object> d5 = HashMap()..addAll(m);
    final Map<Object, Object> d6 = Map.identity()..addAll(m);
    final Map<Object, Object> d7 = HashMap.identity()..addAll(m);
    final Map<Object, Object> d8 = Map.fromEntries(m.entries);
    final Map<Object, Object> d9 = HashMap.fromEntries(m.entries);
    for (final z in [d1, d2, d3, d4, d5, d6, d7, d8, d9]) {
      z.forEach((k, v) {
        c++;
      });
    }
  }
  const totalElements = 108;
  if (c != totalElements) throw StateError('c: $c != $totalElements');
}

/// Command-line arguments:
///
/// `--baseline`: Run additional benchmarks to measure the benchmarking loop
/// component.
///
/// `--cross`: Run additional benchmarks for copying between Map and
/// HashMap.
///
/// `--int`: Run additional benchmarks with `int` keys.
///
/// `--1`: Run additional benchmarks for singleton maps.
///
/// `--all`: Run all benchmark variants.
void main(List<String> commandLineArguments) {
  final arguments = [...commandLineArguments];

  bool includeBaseline = false;
  final Set<String> kinds = {'same'};
  final Set<String> types = {'String', 'Thing'};
  final Set<int> sizes = {2, 100};

  if (arguments.remove('--reset')) {
    kinds.clear();
    types.clear();
    sizes.clear();
  }

  if (arguments.remove('--baseline')) includeBaseline = true;
  if (arguments.remove('--cross')) kinds.add('cross');

  if (arguments.remove('--string')) types.add('String');
  if (arguments.remove('--thing')) types.add('Thing');
  if (arguments.remove('--int')) types.add('int');

  if (arguments.remove('--1')) sizes.add(1);
  if (arguments.remove('--2')) sizes.add(2);
  if (arguments.remove('--100')) sizes.add(100);

  if (arguments.remove('--all')) {
    kinds.addAll(['baseline', 'same', 'cross']);
    types.addAll(['String', 'Thing', 'int']);
    sizes.addAll([1, 2, 100]);
  }

  if (arguments.isNotEmpty) {
    throw ArgumentError('Unused command line arguments: $arguments');
  }

  if (kinds.isEmpty) kinds.add('same');
  if (types.isEmpty) types.add('String');
  if (sizes.isEmpty) sizes.add(2);

  List<Benchmark> makeBenchmarks<K>(int length) {
    return [
      // Map from Map
      if (kinds.contains('same')) ...[
        MapOfBenchmark<K>('Map', length),
        MapCopyOfBenchmark<K>('Map', length),
        MapFromEntriesBenchmark<K>('Map', length),
      ],
      // Map from HashMap
      if (kinds.contains('cross')) ...[
        MapOfBenchmark<K>('HashMap', length),
        MapCopyOfBenchmark<K>('HashMap', length),
        MapFromEntriesBenchmark<K>('HashMap', length),
      ],
      // HashMap from HashMap
      if (kinds.contains('same')) ...[
        HashMapOfBenchmark<K>('HashMap', length),
        HashMapCopyOfBenchmark<K>('HashMap', length),
        HashMapFromEntriesBenchmark<K>('HashMap', length),
      ],
      // HashMap from Map
      if (kinds.contains('cross')) ...[
        HashMapOfBenchmark<K>('Map', length),
        HashMapCopyOfBenchmark<K>('Map', length),
        HashMapFromEntriesBenchmark<K>('Map', length),
      ],
    ];
  }

  List<Benchmark> makeBenchmarksForLength(int length) {
    return [
      if (includeBaseline) BaselineBenchmark(length),
      if (types.contains('String')) ...makeBenchmarks<String>(length),
      if (types.contains('Thing')) ...makeBenchmarks<Thing>(length),
      if (types.contains('int')) ...makeBenchmarks<int>(length),
    ];
  }

  final benchmarks = [
    for (final length in sizes) ...makeBenchmarksForLength(length),
  ];

  // Warmup all benchmarks to ensure JIT compilers see full polymorphism.
  for (var benchmark in benchmarks) {
    pollute();
    benchmark.setup();
  }

  for (var benchmark in benchmarks) {
    pollute();
    benchmark.warmup();
  }

  for (var benchmark in benchmarks) {
    // `report` calls `setup`, but `setup` is idempotent.
    benchmark.report();
  }
}
