// Copyright (c) 2022, 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 'package:benchmark_harness/benchmark_harness.dart';

// Micro-benchmark for List/Map/Set of records.
//
// The goal of this benchmark is to compare and track performance of
// the most common operations on List/Map/Set of records.

int N = 0;
int SUM = 0;

bool runtimeTrue = int.parse('1') == 1; // Not known at compile time.

class Pair {
  final int v0;
  final int v1;
  const Pair(this.v0, this.v1);
  @override
  bool operator ==(other) => other is Pair && v0 == other.v0 && v1 == other.v1;
  @override
  int get hashCode => Object.hash(v0, v1);
}

@pragma('vm:never-inline')
@pragma('wasm:never-inline')
@pragma('dart2js:never-inline')
List<Object> getPolymorphicListOfClass(
  int length,
  bool growable,
  bool withValues,
) {
  if (runtimeTrue) {
    if (withValues) {
      return List<Pair>.generate(length, (i) => Pair(i, i), growable: growable);
    } else {
      return List<Pair>.filled(length, const Pair(-1, -1), growable: growable);
    }
  } else {
    return List<String>.filled(0, '', growable: growable);
  }
}

@pragma('vm:never-inline')
@pragma('wasm:never-inline')
@pragma('dart2js:never-inline')
List<Object> getPolymorphicListOfRecords(
  int length,
  bool growable,
  bool withValues,
) {
  if (runtimeTrue) {
    if (withValues) {
      return List<(int, int)>.generate(
        length,
        (i) => (i, i),
        growable: growable,
      );
    } else {
      return List<(int, int)>.filled(length, (-1, -1), growable: growable);
    }
  } else {
    return List<String>.filled(0, '', growable: growable);
  }
}

class BenchListAddClass extends BenchmarkBase {
  BenchListAddClass() : super('RecordCollections.ListAdd.Class');

  @override
  void run() {
    final list = <Pair>[];
    for (int i = 0; i < N; ++i) {
      list.add(Pair(i, i));
    }
    if (list[N ~/ 2].v0 != N ~/ 2) throw 'Bad result: ${list[N ~/ 2].v0}';
  }
}

class BenchListAddRecord extends BenchmarkBase {
  BenchListAddRecord() : super('RecordCollections.ListAdd.Record');

  @override
  void run() {
    final list = <(int, int)>[];
    for (int i = 0; i < N; ++i) {
      list.add((i, i));
    }
    if (list[N ~/ 2].$1 != N ~/ 2) throw 'Bad result: ${list[N ~/ 2].$1}';
  }
}

class BenchListAddPolyClass extends BenchmarkBase {
  BenchListAddPolyClass() : super('RecordCollections.ListAddPoly.Class');

  @override
  void run() {
    final List<Object> list = getPolymorphicListOfClass(0, runtimeTrue, false);
    for (int i = 0; i < N; ++i) {
      list.add(Pair(i, i));
    }
    final int mid = (list[N ~/ 2] as Pair).v0;
    if (mid != N ~/ 2) throw 'Bad result: $mid';
  }
}

class BenchListAddPolyRecord extends BenchmarkBase {
  BenchListAddPolyRecord() : super('RecordCollections.ListAddPoly.Record');

  @override
  void run() {
    final List<Object> list = getPolymorphicListOfRecords(
      0,
      runtimeTrue,
      false,
    );
    for (int i = 0; i < N; ++i) {
      list.add((i, i));
    }
    final int mid = (list[N ~/ 2] as (int, int)).$1;
    if (mid != N ~/ 2) throw 'Bad result: $mid';
  }
}

class BenchListSetIndexedClass extends BenchmarkBase {
  BenchListSetIndexedClass() : super('RecordCollections.ListSetIndexed.Class');

  @override
  void run() {
    final list = List<Pair>.filled(N, const Pair(-1, -1), growable: false);
    for (int i = 0; i < N; ++i) {
      list[i] = Pair(i, i);
    }
    if (list[N ~/ 2].v0 != N ~/ 2) throw 'Bad result: ${list[N ~/ 2].v0}';
  }
}

class BenchListSetIndexedRecord extends BenchmarkBase {
  BenchListSetIndexedRecord()
    : super('RecordCollections.ListSetIndexed.Record');

  @override
  void run() {
    final list = List<(int, int)>.filled(N, (-1, -1), growable: false);
    for (int i = 0; i < N; ++i) {
      list[i] = (i, i);
    }
    if (list[N ~/ 2].$1 != N ~/ 2) throw 'Bad result: ${list[N ~/ 2].$1}';
  }
}

class BenchListSetIndexedPolyClass extends BenchmarkBase {
  BenchListSetIndexedPolyClass()
    : super('RecordCollections.ListSetIndexedPoly.Class');

  @override
  void run() {
    final List<Object> list = getPolymorphicListOfClass(N, !runtimeTrue, false);
    for (int i = 0; i < N; ++i) {
      list[i] = Pair(i, i);
    }
    final int mid = (list[N ~/ 2] as Pair).v0;
    if (mid != N ~/ 2) throw 'Bad result: $mid';
  }
}

class BenchListSetIndexedPolyRecord extends BenchmarkBase {
  BenchListSetIndexedPolyRecord()
    : super('RecordCollections.ListSetIndexedPoly.Record');

  @override
  void run() {
    final List<Object> list = getPolymorphicListOfRecords(
      N,
      !runtimeTrue,
      false,
    );
    for (int i = 0; i < N; ++i) {
      list[i] = (i, i);
    }
    final int mid = (list[N ~/ 2] as (int, int)).$1;
    if (mid != N ~/ 2) throw 'Bad result: $mid';
  }
}

class BenchListGetIndexedClass extends BenchmarkBase {
  BenchListGetIndexedClass() : super('RecordCollections.ListGetIndexed.Class');

  final list = <Pair>[for (int i = 0; i < N; ++i) Pair(i, i)];

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < list.length; ++i) {
      sum += list[i].v0;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchListGetIndexedRecord extends BenchmarkBase {
  BenchListGetIndexedRecord()
    : super('RecordCollections.ListGetIndexed.Record');

  final list = <(int, int)>[for (int i = 0; i < N; ++i) (i, i)];

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < list.length; ++i) {
      sum += list[i].$1;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchListGetIndexedPolyClass extends BenchmarkBase {
  BenchListGetIndexedPolyClass()
    : super('RecordCollections.ListGetIndexedPoly.Class');

  final list = getPolymorphicListOfClass(N, runtimeTrue, true) as List<Pair>;

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < list.length; ++i) {
      sum += list[i].v0;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchListGetIndexedPolyRecord extends BenchmarkBase {
  BenchListGetIndexedPolyRecord()
    : super('RecordCollections.ListGetIndexedPoly.Record');

  final list =
      getPolymorphicListOfRecords(N, runtimeTrue, true) as List<(int, int)>;

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < list.length; ++i) {
      sum += list[i].$1;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchListIterateClass extends BenchmarkBase {
  BenchListIterateClass() : super('RecordCollections.ListIterate.Class');

  final list = <Pair>[for (int i = 0; i < N; ++i) Pair(i, i)];

  @override
  void run() {
    int sum = 0;
    for (final v in list) {
      sum += v.v0;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchListIterateRecord extends BenchmarkBase {
  BenchListIterateRecord() : super('RecordCollections.ListIterate.Record');

  final list = <(int, int)>[for (int i = 0; i < N; ++i) (i, i)];

  @override
  void run() {
    int sum = 0;
    for (final v in list) {
      sum += v.$1;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchListIteratePolyClass extends BenchmarkBase {
  BenchListIteratePolyClass()
    : super('RecordCollections.ListIteratePoly.Class');

  final list = getPolymorphicListOfClass(N, runtimeTrue, true) as List<Pair>;

  @override
  void run() {
    int sum = 0;
    for (final v in list) {
      sum += v.v0;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchListIteratePolyRecord extends BenchmarkBase {
  BenchListIteratePolyRecord()
    : super('RecordCollections.ListIteratePoly.Record');

  final list =
      getPolymorphicListOfRecords(N, runtimeTrue, true) as List<(int, int)>;

  @override
  void run() {
    int sum = 0;
    for (final v in list) {
      sum += v.$1;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchMapAddClassKey extends BenchmarkBase {
  BenchMapAddClassKey() : super('RecordCollections.MapAdd.ClassKey');

  @override
  void run() {
    final map = <Pair, int>{};
    for (int i = 0; i < N; ++i) {
      map[Pair(i, i)] = i;
    }
    if (map.length != N) throw 'Bad result: ${map.length}';
  }
}

class BenchMapAddRecordKey extends BenchmarkBase {
  BenchMapAddRecordKey() : super('RecordCollections.MapAdd.RecordKey');

  @override
  void run() {
    final map = <(int, int), int>{};
    for (int i = 0; i < N; ++i) {
      map[(i, i)] = i;
    }
    if (map.length != N) throw 'Bad result: ${map.length}';
  }
}

class BenchMapAddClassValue extends BenchmarkBase {
  BenchMapAddClassValue() : super('RecordCollections.MapAdd.ClassValue');

  @override
  void run() {
    final map = <int, Pair>{};
    for (int i = 0; i < N; ++i) {
      map[i] = Pair(i, i);
    }
    if (map.length != N) throw 'Bad result: ${map.length}';
  }
}

class BenchMapAddRecordValue extends BenchmarkBase {
  BenchMapAddRecordValue() : super('RecordCollections.MapAdd.RecordValue');

  @override
  void run() {
    final map = <int, (int, int)>{};
    for (int i = 0; i < N; ++i) {
      map[i] = (i, i);
    }
    if (map.length != N) throw 'Bad result: ${map.length}';
  }
}

class BenchMapLookupClass extends BenchmarkBase {
  BenchMapLookupClass() : super('RecordCollections.MapLookup.Class');

  final map = <Pair, int>{for (int i = 0; i < N; ++i) Pair(i, i): i};

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < N; ++i) {
      sum += map[Pair(i, i)]!;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchMapLookupRecord extends BenchmarkBase {
  BenchMapLookupRecord() : super('RecordCollections.MapLookup.Record');

  final map = <(int, int), int>{for (int i = 0; i < N; ++i) (i, i): i};

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < N; ++i) {
      sum += map[(i, i)]!;
    }
    if (sum != SUM) throw 'Bad result: $sum';
  }
}

class BenchSetAddClass extends BenchmarkBase {
  BenchSetAddClass() : super('RecordCollections.SetAdd.Class');

  @override
  void run() {
    final set = <Pair>{};
    for (int i = 0; i < N; ++i) {
      set.add(Pair(i, i));
    }
    if (set.length != N) throw 'Bad result: ${set.length}';
  }
}

class BenchSetAddRecord extends BenchmarkBase {
  BenchSetAddRecord() : super('RecordCollections.SetAdd.Record');

  @override
  void run() {
    final set = <(int, int)>{};
    for (int i = 0; i < N; ++i) {
      set.add((i, i));
    }
    if (set.length != N) throw 'Bad result: ${set.length}';
  }
}

class BenchSetLookupClass extends BenchmarkBase {
  BenchSetLookupClass() : super('RecordCollections.SetLookup.Class');

  final set = <Pair>{for (int i = 0; i < N ~/ 2; ++i) Pair(i * 2, i * 2)};

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < N; ++i) {
      sum += set.contains(Pair(i, i)) ? 1 : 0;
    }
    if (sum != N ~/ 2) throw 'Bad result: $sum';
  }
}

class BenchSetLookupRecord extends BenchmarkBase {
  BenchSetLookupRecord() : super('RecordCollections.SetLookup.Record');

  final set = <(int, int)>{for (int i = 0; i < N ~/ 2; ++i) (i * 2, i * 2)};

  @override
  void run() {
    int sum = 0;
    for (int i = 0; i < N; ++i) {
      sum += set.contains((i, i)) ? 1 : 0;
    }
    if (sum != N ~/ 2) throw 'Bad result: $sum';
  }
}

void main() {
  N = int.parse('100000');
  SUM = N * (N - 1) ~/ 2;

  final benchmarks = [
    BenchListAddClass(),
    BenchListAddRecord(),
    BenchListAddPolyClass(),
    BenchListAddPolyRecord(),
    BenchListSetIndexedClass(),
    BenchListSetIndexedRecord(),
    BenchListSetIndexedPolyClass(),
    BenchListSetIndexedPolyRecord(),
    BenchListGetIndexedClass(),
    BenchListGetIndexedRecord(),
    BenchListGetIndexedPolyClass(),
    BenchListGetIndexedPolyRecord(),
    BenchListIterateClass(),
    BenchListIterateRecord(),
    BenchListIteratePolyClass(),
    BenchListIteratePolyRecord(),
    BenchMapAddClassKey(),
    BenchMapAddRecordKey(),
    BenchMapAddClassValue(),
    BenchMapAddRecordValue(),
    BenchMapLookupClass(),
    BenchMapLookupRecord(),
    BenchSetAddClass(),
    BenchSetAddRecord(),
    BenchSetLookupClass(),
    BenchSetLookupRecord(),
  ];

  for (final benchmark in benchmarks) {
    benchmark.warmup();
  }
  for (final benchmark in benchmarks) {
    benchmark.report();
  }
}
