// Copyright (c) 2025, 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';
import 'dart:ffi';

final repoRoot = File.fromUri(Platform.script).parent.parent.parent.path;
final runtimeRoot = '$repoRoot/runtime';
final buildtoolsRoot = '$repoRoot/buildtools';
final clangBinDir =
    '$buildtoolsRoot/$currentPlatformBuildtoolsSubdir/clang/bin';
final clangFormatBin = '$clangBinDir/clang-format';

final currentPlatformBuildtoolsSubdir = switch (Abi.current()) {
  Abi.macosX64 => 'mac-x64',
  Abi.macosArm64 => 'mac-arm64',
  Abi.linuxX64 => 'linux-x64',
  Abi.linuxArm64 => 'linux-arm64',
  Abi.windowsX64 => 'win-x64',
  Abi.windowsArm64 => 'win-arm64',
  _ => throw UnimplementedError(),
};

void main(List<String> args) {
  final checkUpToDate = args.contains('--check-up-to-date');

  final dartApiHFile = File('$runtimeRoot/include/dart_api.h');
  final dartNativeApiHFile = File('$runtimeRoot/include/dart_native_api.h');
  final dartApiWinCFile = File('$runtimeRoot/bin/dart_api_win.c');
  final dartApiWinCTmpFile = File('$runtimeRoot/bin/dart_api_win_tmp.c');
  final dartApiHContents = dartApiHFile.readAsStringSync();
  final dartNativeApiHContents = dartNativeApiHFile.readAsStringSync();

  final procedureRegexp = RegExp(
    r'(DART_\w+\s+)+(?<returnType>[\w\s\*]+)\s+(?<name>\w+)\((?<arguments>[^)]*)\);',
    multiLine: true,
  );

  final matches = [
    ...procedureRegexp.allMatches(dartApiHContents),
    ...procedureRegexp.allMatches(dartNativeApiHContents),
  ];

  final procedures = <Procedure>[];

  for (final match in matches) {
    final returnType = match.namedGroup('returnType')!;
    final name = match.namedGroup('name')!;
    final argumentsString = match.namedGroup('arguments') ?? '';
    final argumentList =
        argumentsString.split(',').where((arg) => arg != 'void').map((arg) {
          final parts = arg.trim().split(' ');
          return (
            type: parts.sublist(0, parts.length - 1).join(' '),
            name: parts[parts.length - 1],
          );
        }).toList();
    procedures.add((
      name: name,
      returnType: returnType,
      arguments: argumentList,
    ));
  }

  final buffer = StringBuffer();

  buffer.writeln('''
// Copyright (c) 2025, 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.

// DO NOT EDIT. This file is generated by runtime/tools/generate_dart_api_win_c.dart.

#include <windows.h>

#include <include/dart_api.h>
#include <include/dart_native_api.h>

''');

  // Generate typedefs for all procedures.
  for (final procedure in procedures) {
    buffer.write('typedef ');
    buffer.write(procedure.returnType);
    buffer.write(' (*');
    buffer.write(procedure.typedefName);
    buffer.write(')(');
    for (final (i, argument) in procedure.arguments.indexed) {
      buffer.write(argument.type);
      if (i < procedure.arguments.length - 1) {
        buffer.write(', ');
      }
    }
    buffer.writeln(');');
  }

  buffer.writeln();

  // Generate function pointers for all procedures.
  for (final procedure in procedures) {
    buffer.write('static ');
    buffer.write(procedure.typedefName);
    buffer.write(' ');
    buffer.write(procedure.functionPointerName);
    buffer.writeln(' = NULL;');
  }

  buffer.writeln();

  // Generate the DllMain function that initializes all function pointers.
  buffer.writeln('''
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
  if (fdwReason == DLL_PROCESS_ATTACH) {
    HMODULE process = GetModuleHandle(NULL);
''');

  for (final procedure in procedures) {
    buffer.write('    ');
    buffer.write(procedure.functionPointerName);
    buffer.write(' = (');
    buffer.write(procedure.typedefName);
    buffer.write(') GetProcAddress(process, "');
    buffer.write(procedure.name);
    buffer.writeln('");');
  }

  buffer.writeln('''
  }

  return TRUE;
}''');

  buffer.writeln();

  // Generate redirecting implementations for all procedures.
  for (final procedure in procedures) {
    final (:name, :returnType, :arguments) = procedure;
    buffer.write(returnType);
    buffer.write(' ');
    buffer.write(name);
    buffer.write('(');
    for (final (i, (:name, :type)) in arguments.indexed) {
      buffer.write(type);
      buffer.write(' ');
      buffer.write(name);
      if (i < arguments.length - 1) {
        buffer.write(', ');
      }
    }
    buffer.writeln(') {');
    buffer.write('  ');
    if (procedure.returnType != 'void') {
      buffer.write('return ');
    }
    buffer.write(procedure.functionPointerName);
    buffer.write('(');
    for (final (i, argument) in arguments.indexed) {
      buffer.write(argument.name);
      if (i < arguments.length - 1) {
        buffer.write(', ');
      }
    }
    buffer.writeln(');');
    buffer.writeln('}');
    buffer.writeln();
  }

  buffer.writeln();

  dartApiWinCTmpFile.writeAsStringSync(buffer.toString());

  try {
    // Run clang-format on the generated file.
    final clangFormatResult = Process.runSync(
      clangFormatBin,
      ['-i', dartApiWinCTmpFile.path],
      // Allows us to specify the path to the clang-format binary without the
      // .exe extension on Windows.
      runInShell: Platform.isWindows,
    );
    if (clangFormatResult.exitCode != 0) {
      print(clangFormatResult.stdout);
      print(clangFormatResult.stderr);
      exitCode = 1;
    } else {
      final changed =
          !dartApiWinCFile.existsSync() ||
          dartApiWinCTmpFile.readAsStringSync() !=
              dartApiWinCFile.readAsStringSync();
      if (changed) {
        if (checkUpToDate) {
          exitCode = 1;
        } else {
          dartApiWinCTmpFile.copySync(dartApiWinCFile.path);
        }
      }
    }
  } finally {
    dartApiWinCTmpFile.deleteSync();
  }
}

typedef Procedure =
    ({
      String name,
      String returnType,
      List<({String name, String type})> arguments,
    });

extension on Procedure {
  String get typedefName => '${name}Type';
  String get functionPointerName => '${name}Fn';
}
