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

import 'dart:io';

//
// Configuration.
//

const nativeToDartType = {
  'Int8': 'int',
  'Int16': 'int',
  'Int32': 'int',
  'Int64': 'int',
  'Uint8': 'int',
  'Uint16': 'int',
  'Uint32': 'int',
  'Uint64': 'int',
  'Float': 'double',
  'Double': 'double',
  'Pointer<Uint8>': 'Pointer<Uint8>',
  'Handle': 'Object',
};

const generateFor = {
  'Int8': [1],
  'Int16': [1],
  'Int32': [1, 2, 4, 10, 20],
  'Int64': [1, 2, 4, 10, 20],
  'Uint8': [1],
  'Uint16': [1],
  'Uint32': [1],
  'Uint64': [1],
  'Float': [1, 2, 4, 10, 20],
  'Double': [1, 2, 4, 10, 20],
  'Pointer<Uint8>': [1, 2, 4, 10, 20],
  'Handle': [1, 2, 4, 10, 20],
};

const allNumbers = [1, 2, 4, 10, 20];

//
// Generator.
//

void main() {
  final List<String> nativeTypes = nativeToDartType.keys.toList();
  final List<String> dartTypes = nativeToDartType.values.toSet().toList();
  final List<String> nativeIntTypes = nativeTypes.where(isInt).toList();
  final List<String> nativeDoubleTypes = nativeTypes.where(isDouble).toList();
  final List<String> nativePointerTypes = nativeTypes.where(isPointer).toList();
  final List<String> nativeHandleTypes = nativeTypes.where(isHandle).toList();

  final StringBuffer buffer = StringBuffer();
  buffer.write(header);
  generateTypedefs(buffer, 'Function', dartTypes, allNumbers);
  generateTypedefs(buffer, 'NativeFunction', nativeTypes, allNumbers);
  generateBenchmarkInt(buffer, nativeIntTypes);
  generateBenchmarkDouble(buffer, nativeDoubleTypes);
  generateBenchmarkPointer(buffer, nativePointerTypes);
  generateBenchmarkHandle(buffer, nativeHandleTypes);

  final path = Platform.script.resolve('dart/benchmark_generated.dart').path;
  File(path).writeAsStringSync(buffer.toString());
  print(Process.runSync('dart', ['format', path]).stderr);
}

const header = '''
// 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.
//
// This file has been automatically generated. Please do not edit it manually.
// To regenerate the file, run the following script:
//
// > dart benchmarks/FfiCall/generate_benchmarks.dart

// Using part of, so that the library uri is identical to the main file.
// That way the FfiNativeResolver works for the main uri.
part of 'FfiCall.dart';

''';

void generateTypedefs(
  StringBuffer buffer,
  String namePrefix,
  List<String> types,
  List<int> numbers,
) {
  for (String type in types) {
    for (int number in numbers) {
      final String name = '$namePrefix$number${toIdentifier(type)}';
      final String arguments = repeat(type, number, ', ');
      buffer.write('typedef $name = $type Function($arguments);');
    }
  }
}

void generateBenchmarkInt(StringBuffer buffer, List<String> types) {
  for (String type in types) {
    final String typeName = toIdentifier(type);
    final String dartType = toIdentifier(nativeToDartType[type]!);
    for (int number in generateFor[type]!) {
      final String name = '${typeName}x${'$number'.padLeft(2, '0')}';
      final String expected = IntVariation(type, number).expectedValue(number);
      final String functionType = 'Function$number$dartType';
      final String functionNativeType = 'NativeFunction$number$typeName';
      final String functionNameC = 'Function$number$typeName';
      final String argument = IntVariation(type, number).argument;
      final String arguments = repeat(argument, number, ', ');
      final String functionNameDart = 'function$number$typeName';
      final String dartArguments = List.generate(
        number,
        (i) => '$dartType a$i',
      ).join(', ');

      buffer.write('''
class $name extends FfiBenchmarkBase {
  final $functionType f;

  $name({bool isLeaf = false})
        : f = isLeaf
            ? ffiTestFunctions.lookupFunction<$functionNativeType,$functionType>('$functionNameC', isLeaf: true)
            : ffiTestFunctions.lookupFunction<$functionNativeType,$functionType>('$functionNameC', isLeaf: false),
        super('FfiCall.$name', isLeaf: isLeaf);

  @override
  void run() {
    int x = 0;
    for (int i = 0; i < N; i++) {
      x += f($arguments);
    }
    expectEquals(x, $expected);
  }
}
''');

      for (bool isLeaf in [false, true]) {
        final leaf = isLeaf ? 'Leaf' : '';
        buffer.write('''
@Native<$functionNativeType>(symbol: '$functionNameC', isLeaf: $isLeaf)
external $dartType $functionNameDart$leaf($dartArguments);

class ${name}Native$leaf extends FfiBenchmarkBase {
  ${name}Native$leaf() : super('FfiCall.${name}Native', isLeaf: $isLeaf);

  @override
  void run() {
    int x = 0;
    for (int i = 0; i < N; i++) {
      x += $functionNameDart$leaf($arguments);
    }
    expectEquals(x, $expected);
  }
}
''');
      }
    }
  }
}

void generateBenchmarkDouble(StringBuffer buffer, List<String> types) {
  for (String type in types) {
    final String typeName = toIdentifier(type);
    final String dartType = toIdentifier(nativeToDartType[type]!);
    for (int number in generateFor[type]!) {
      final String name = '${typeName}x${'$number'.padLeft(2, '0')}';
      final String expected = number == 1
          ? 'N + N * 42.0' // Do work with single arg.
          : 'N * $number * ($number + 1) / 2 '; // The rest sums arguments.
      final String functionType = 'Function$number$dartType';
      final String functionNativeType = 'NativeFunction$number$typeName';
      final String functionNameC = 'Function$number$typeName';
      final List<double> argVals = List.generate(number, (i) => 1.0 * (i + 1));
      final String arguments = argVals.join(', ');
      final String functionNameDart = 'function$number$typeName';
      final String dartArguments = List.generate(
        number,
        (i) => '$dartType a$i',
      ).join(', ');
      buffer.write('''
class $name extends FfiBenchmarkBase {
  final $functionType f;

  $name({bool isLeaf = false})
        : f = isLeaf
            ? ffiTestFunctions.lookupFunction<$functionNativeType,$functionType>('$functionNameC', isLeaf: true)
            : ffiTestFunctions.lookupFunction<$functionNativeType,$functionType>('$functionNameC', isLeaf: false),
        super('FfiCall.$name', isLeaf: isLeaf);

  @override
  void run() {
    double x = 0;
    for (int i = 0; i < N; i++) {
      x += f($arguments);
    }
    final double expected = $expected;
    expectApprox(x, expected);
  }
}
''');

      for (bool isLeaf in [false, true]) {
        final leaf = isLeaf ? 'Leaf' : '';
        buffer.write('''
@Native<$functionNativeType>(symbol: '$functionNameC', isLeaf: $isLeaf)
external $dartType $functionNameDart$leaf($dartArguments);

class ${name}Native$leaf extends FfiBenchmarkBase {
  ${name}Native$leaf() : super('FfiCall.${name}Native', isLeaf: $isLeaf);

  @override
  void run() {
    double x = 0;
    for (int i = 0; i < N; i++) {
      x += $functionNameDart$leaf($arguments);
    }
    final double expected = $expected;
    expectApprox(x, expected);
  }
}
''');
      }
    }
  }
}

void generateBenchmarkPointer(StringBuffer buffer, List<String> types) {
  for (String type in types) {
    if (type != 'Pointer<Uint8>') throw Exception('Not implemented for $type.');
    final String typeName = toIdentifier(type);
    final String dartType = nativeToDartType[type]!;
    final String dartTypeName = toIdentifier(dartType);
    for (int number in generateFor[type]!) {
      final String name = '${typeName}x${'$number'.padLeft(2, '0')}';
      final List<String> pointerNames = List.generate(
        number,
        (i) => 'p${i + 1}',
      );
      final String pointers = pointerNames
          .map((n) => '$type $n = nullptr;')
          .join('\n');
      final String setup = List.generate(
        number - 1,
        (i) => 'p${i + 2} = p1 + ${i + 1};',
      ).join();
      final String functionType = 'Function$number$dartTypeName';
      final String functionNativeType = 'NativeFunction$number$typeName';
      final String functionNameC = 'Function$number$typeName';
      final String arguments = pointerNames.skip(1).join(', ');
      final String functionNameDart = 'function$number$typeName';
      final String dartArguments = List.generate(
        number,
        (i) => '$dartType a$i',
      ).join(', ');
      buffer.write('''
class $name extends FfiBenchmarkBase {
  final $functionType f;

  $name({bool isLeaf = false})
        : f = isLeaf
            ? ffiTestFunctions.lookupFunction<$functionNativeType,$functionType>('$functionNameC', isLeaf: true)
            : ffiTestFunctions.lookupFunction<$functionNativeType,$functionType>('$functionNameC', isLeaf: false),
        super('FfiCall.$name', isLeaf: isLeaf);

  $pointers

  @override
  void setup() {
    p1 = calloc(N + 1);
    $setup
  }

  @override
  void teardown() {
    calloc.free(p1);
  }

  @override
  void run() {
  $type x = p1;
    for (int i = 0; i < N; i++) {
      x = f(x, $arguments);
    }
    expectEquals(x.address, p1.address + N * sizeOf<Uint8>());
  }
}
''');

      for (bool isLeaf in [false, true]) {
        final leaf = isLeaf ? 'Leaf' : '';
        buffer.write('''
@Native<$functionNativeType>(symbol: '$functionNameC', isLeaf: $isLeaf)
external $dartType $functionNameDart$leaf($dartArguments);

class ${name}Native$leaf extends FfiBenchmarkBase {
  ${name}Native$leaf() : super('FfiCall.${name}Native', isLeaf: $isLeaf);

  $pointers

  @override
  void setup() {
    p1 = calloc(N + 1);
    $setup
  }

  @override
  void teardown() {
    calloc.free(p1);
  }

  @override
  void run() {
  $type x = p1;
    for (int i = 0; i < N; i++) {
      x = $functionNameDart$leaf(x, $arguments);
    }
    expectEquals(x.address, p1.address + N * sizeOf<Uint8>());
  }
}
''');
      }
    }
  }
}

void generateBenchmarkHandle(StringBuffer buffer, List<String> types) {
  for (String type in types) {
    if (type != 'Handle') throw Exception('Not implemented for $type.');
    final String typeName = toIdentifier(type);
    final String dartType = toIdentifier(nativeToDartType[type]!);
    for (int number in generateFor[type]!) {
      final String name = '${typeName}x${'$number'.padLeft(2, '0')}';
      final String setup = List.generate(
        number + 1,
        (i) => 'final m$i = MyClass($i);',
      ).skip(2).join('\n');
      final String functionType = 'Function$number$dartType';
      final String functionNativeType = 'NativeFunction$number$typeName';
      final String functionNameC = 'Function$number$typeName';
      final String arguments = List.generate(
        number - 1,
        (i) => 'm${i + 2}',
      ).join(', ');
      final String functionNameDart = 'function$number$typeName';
      final String dartArguments = List.generate(
        number,
        (i) => '$dartType a$i',
      ).join(', ');
      buffer.write('''
class $name extends FfiBenchmarkBase {
  final $functionType f;

  $name()
        : f = ffiTestFunctions.lookupFunction<$functionNativeType,$functionType>('$functionNameC', isLeaf: false),
        super('FfiCall.$name', isLeaf: false);

  @override
  void run() {
    final m1 = MyClass(123);
    $setup
    Object x = m1;
    for (int i = 0; i < N; i++) {
      x = f(x, $arguments);
    }
    expectIdentical(x, m1);
  }
}

@Native<$functionNativeType>(symbol: '$functionNameC', isLeaf: false)
external $dartType $functionNameDart($dartArguments);

class ${name}Native extends FfiBenchmarkBase {
  ${name}Native() : super('FfiCall.${name}Native', isLeaf: false);

  @override
  void run() {
    final m1 = MyClass(123);
    $setup
    Object x = m1;
    for (int i = 0; i < N; i++) {
      x = $functionNameDart(x, $arguments);
    }
    expectIdentical(x, m1);
  }
}
''');
    }
  }
}

//
// Benchmark variations.
//

class IntVariation {
  /// The argument passed to the C function, the same value is passed if the C
  /// function has multiple parameters.
  final String argument;

  /// The expected value of summation of all return values.
  final String Function(int number) expectedValue;

  /// These benchmarks sum all arguments over all iterations.
  IntVariation.LargeIntManyArguments()
    : argument = 'i',
      expectedValue = ((int number) => 'N * (N - 1) * $number / 2');

  /// Benchmarks with only one argument return 42 added to the argument.
  IntVariation.LargeIntOneArgument()
    : argument = 'i',
      expectedValue = ((int number) => 'N * (N - 1) / 2 + N * 42');

  /// The benchmarks with small ints (`int8_t`, `uint8_t`, etc.) we pass an
  /// arbitrary fixed argument between 0 and 127 to prevent truncation.
  ///
  /// The C function returns 42 added to the argument.
  IntVariation.SmallInt()
    : argument = '17',
      expectedValue = ((int number) => 'N * 17 + N * 42');

  factory IntVariation(String type, int number) {
    if (isSmallInt(type)) {
      return IntVariation.SmallInt();
    }
    if (number == 1) {
      return IntVariation.LargeIntOneArgument();
    }
    return IntVariation.LargeIntManyArguments();
  }
}

//
// Helper functions.
//

String toIdentifier(String type) =>
    type.replaceAll('<', '').replaceAll('>', '');

String repeat(String input, int n, String separator) {
  if (n == 0) {
    return '';
  }

  return (input + separator) * (n - 1) + input;
}

bool isInt(String type) => type.startsWith('Int') || type.startsWith('Uint');

/// True for `int8_t`, `uint8_t`, `int16_t`, and `uint16_t`.
bool isSmallInt(String type) =>
    isInt(type) && (type.contains('8') || type.contains('16'));

bool isDouble(String type) =>
    type.startsWith('Float') || type.startsWith('Double');

bool isPointer(String type) => type.startsWith('Pointer');

bool isHandle(String type) => type == 'Handle';
