// 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:collection';
import 'dart:io';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:io/ansi.dart' as ansi;

import 'package:path/path.dart' as p;

final bindingsGeneratorPath = p.fromUri(Platform.script.resolve('../lib/src'));

Future<void> compileDartMain({String? langVersion, String? dir}) async {
  await runProc(
    Platform.executable,
    [
      'compile',
      'js',
      '--enable-asserts',
      '--server-mode',
      if (langVersion != null) '-DlanguageVersion=$langVersion',
      'dart_main.dart',
      '-o',
      'dart_main.js',
    ],
    workingDirectory: dir ?? bindingsGeneratorPath,
  );
}

Future<Process> runProcWithResult(String executable, List<String> arguments,
    {required String workingDirectory}) async {
  print(ansi.styleBold.wrap(['*', executable, ...arguments].join(' ')));
  return Process.start(
    executable,
    arguments,
    runInShell: Platform.isWindows,
    workingDirectory: workingDirectory,
  );
}

Future<void> runProc(String executable, List<String> arguments,
    {required String workingDirectory, bool detached = false}) async {
  print(ansi.styleBold.wrap(['*', executable, ...arguments].join(' ')));
  final proc = await Process.start(
    executable,
    arguments,
    mode: detached ? ProcessStartMode.detached : ProcessStartMode.inheritStdio,
    runInShell: Platform.isWindows,
    workingDirectory: workingDirectory,
  );
  final procExit = await proc.exitCode;
  if (procExit != 0) {
    throw ProcessException(executable, arguments, 'Process failed', procExit);
  }
}

Future<File> createJsTypeSupertypeContext() async {
  final contextFile =
      await File(p.join(bindingsGeneratorPath, '_js_supertypes_src.dart'))
          .create();
  await contextFile.writeAsString('''
import 'dart:js_interop';

@JS()
external JSPromise get promise;
''');
  return contextFile;
}

/// Generates a map of the JS type hierarchy defined in `dart:js_interop` that's
/// used by both translators.
Future<void> generateJsTypeSupertypes(String contextFile) async {
  // Use a file that uses `dart:js_interop` for analysis.
  final contextCollection =
      AnalysisContextCollection(includedPaths: [contextFile]);
  final dartJsInterop = (await contextCollection.contexts.single.currentSession
          .getLibraryByUri('dart:js_interop') as LibraryElementResult)
      .element2;
  final definedNames = dartJsInterop.exportNamespace.definedNames2;
  // `SplayTreeMap` to avoid moving types around in `dart:js_interop` affecting
  // the code generation.
  final jsTypeSupertypes = SplayTreeMap<String, String?>();
  for (final name in definedNames.keys) {
    final element = definedNames[name];
    if (element is ExtensionTypeElement2) {
      // JS types are any extension type that starts with 'JS' in
      // `dart:js_interop`.
      bool isJSType(InterfaceElement2 element) =>
          element is ExtensionTypeElement2 &&
          element.library2 == dartJsInterop &&
          element.name3!.startsWith('JS');
      if (!isJSType(element)) continue;

      String? parentJsType;
      final supertype = element.supertype;
      final immediateSupertypes = <InterfaceType>[
        if (supertype != null) supertype,
        ...element.interfaces,
      ]..removeWhere((supertype) => supertype.isDartCoreObject);
      // We should have at most one non-trivial supertype.
      assert(immediateSupertypes.length <= 1);
      for (final supertype in immediateSupertypes) {
        if (isJSType(supertype.element3)) {
          parentJsType = "'${supertype.element3.name3!}'";
        }
      }
      // Ensure that the hierarchy forms a tree.
      assert((parentJsType == null) == (name == 'JSAny'));
      jsTypeSupertypes["'$name'"] = parentJsType;
    }
  }

  final jsTypeSupertypesScript = '''
// 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.

// Do not modify by hand.

const Map<String, String?> jsTypeSupertypes = {
${jsTypeSupertypes.entries.map((e) => "  ${e.key}: ${e.value},").join('\n')}
};
''';
  final jsTypeSupertypesPath =
      p.join(bindingsGeneratorPath, 'js_type_supertypes.dart');
  await File(jsTypeSupertypesPath).writeAsString(jsTypeSupertypesScript);
}
