// 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 'package:args/args.dart';
import 'package:kernel/ast.dart' show Library;
import 'package:kernel/kernel.dart' show loadComponentFromBinary;
import 'package:path/path.dart' as path;
import 'package:vm/embedder/visitor.dart' as visitor show visitLibrary;
import 'package:vm/embedder/writer.dart' show EntryPointShimWriter;

final String _usage = '''
Usage: generate_entry_point_shims [options] source.dill out/basename

Creates appropriate entry point shims for the entry points in the component
encoded by the provided dill. If the component has a main method, then only
translates entry points in the same package as the main method, otherwise
requires a package to be specified via the command-line options.

out/basename.h contains the declarations of the shim functions and
out/basename.cc contains the definitions.

Options:
''';

void main(List<String> args) async {
  final parser =
      ArgParser()
        ..addFlag(
          'uninitialized',
          abbr: 'u',
          help:
              'Create allocation and initializion methods for uninitialized instances',
        )
        ..addFlag(
          'error-unhandled',
          abbr: 'e',
          help: 'Error for entry points that cannot be shimmed',
        )
        ..addFlag(
          'help',
          abbr: 'h',
          help: 'Prints usage information and exits',
          negatable: false,
        )
        ..addOption(
          'package',
          abbr: 'p',
          help: 'Consider entry points only from the specified package',
          valueHelp: 'URI',
        );

  Never usageFail([String? prefix]) {
    if (prefix != null) {
      print(prefix);
      print('');
    }
    print(_usage);
    print(parser.usage);
    exit(1);
  }

  final argResults = parser.parse(args);
  if (argResults['help'] || argResults.rest.length != 2) {
    usageFail();
  }

  final outputPath = path.normalize(argResults.rest[1]);
  final outputDir = Directory(path.dirname(outputPath));
  if (!outputDir.existsSync()) {
    outputDir.createSync(recursive: true);
  }

  final source = argResults.rest[0];
  final component = loadComponentFromBinary(source);
  Library? library;

  final uriString = argResults['package'];
  if (uriString == null) {
    final mainMethod = component.mainMethod;
    if (mainMethod == null) {
      usageFail('No main method found, so -p/--package is required.');
    }
  } else {
    final uri = Uri.tryParse(uriString);
    if (uri == null) {
      usageFail('${argResults['package']} is not a valid URI.');
    }
    for (final l in component.libraries) {
      if (l.importUri == uri) {
        library = l;
        break;
      }
    }
    if (library == null) {
      usageFail('No package found with URI ${argResults['package']}.');
    }
  }

  final createUninitializedInstanceMethods = argResults['uninitialized'];
  final collector = visitor.visitLibrary(
    component,
    library ?? component.mainMethod!.enclosingLibrary,
    createUninitializedInstanceMethods: createUninitializedInstanceMethods,
    errorOnUnhandledEntryPoints: argResults['error-unhandled'],
  );

  final declarations = StringBuffer();
  final definitions = StringBuffer();

  for (final buffer in [declarations, definitions]) {
    buffer.write('''
/*
   Generated with:
     dart pkg/vm/tool/generate_entry_point_shims.dart \\
         ''');
    if (createUninitializedInstanceMethods) {
      buffer.write('-u ');
    }
    if (uriString != null) {
      buffer.write('''-p $uriString \\
         ''');
    }
    buffer.writeln('''$source \\
         $outputPath
*/
''');
  }

  final headerPath = outputPath + '.h';
  final writer = EntryPointShimWriter(headerPath, library, collector);
  writer.write(declarations, definitions);

  final implPath = outputPath + '.cc';
  File(headerPath).writeAsStringSync(declarations.toString(), flush: true);
  File(implPath).writeAsStringSync(definitions.toString(), flush: true);
}
