// Copyright (c) 2024, 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:logging/logging.dart';
import 'package:path/path.dart' as path;

import 'config.dart';
import 'context.dart';
import 'generator/generator.dart';
import 'parser/parser.dart';
import 'transformer/transform.dart';
import 'utils.dart';

extension Swift2ObjCGeneratorMethod on Swift2ObjCGenerator {
  /// Used to generate the wrapper swift file.
  Future<void> generate({required Logger? logger}) => _generateWrapper(
    this,
    Context(logger ?? (Logger.detached('dev/null')..level = Level.OFF)),
  );
}

Future<void> _generateWrapper(
  Swift2ObjCGenerator config,
  Context context,
) async {
  final Directory tempDir;
  final bool deleteTempDirWhenDone;

  var lazyTarget = config.target;
  Future<String> target() async => lazyTarget ??= await hostTargetTriple;
  var lazySdkPath = config.sdk;
  Future<Uri> sdkPath() async => lazySdkPath ??= await hostSdk;

  if (config.tempDir == null) {
    tempDir = Directory.systemTemp.createTempSync(defaultTempDirPrefix);
    deleteTempDirWhenDone = true;
  } else {
    tempDir = Directory.fromUri(config.tempDir!);
    deleteTempDirWhenDone = false;
  }
  tempDir.createSync();

  final sourceModules = <String?>[];
  final mergedSymbolgraph = ParsedSymbolgraph();

  final allInputConfigs = [...config.inputs, builtInInputConfig];

  for (final input in allInputConfigs) {
    if (input is HasSymbolgraphCommand) {
      await _generateSymbolgraphJson(
        (input as HasSymbolgraphCommand).symbolgraphCommand(
          await target(),
          path.absolute((await sdkPath()).path),
        ),
        tempDir,
      );
    }

    final symbolgraphFileName = switch (input) {
      FilesInputConfig() => '${input.tempModuleName}$symbolgraphFileSuffix',
      ModuleInputConfig() => '${input.module}$symbolgraphFileSuffix',
      JsonFileInputConfig() => path.absolute(input.jsonFile.path),
    };
    final symbolgraphJsonPath = path.join(tempDir.path, symbolgraphFileName);
    final symbolgraphJson = readJsonFile(symbolgraphJsonPath);

    sourceModules.add(switch (input) {
      FilesInputConfig() => null,
      ModuleInputConfig() => input.module,
      JsonFileInputConfig() => parseModuleName(symbolgraphJson),
    });
    mergedSymbolgraph.merge(parseSymbolgraph(input, symbolgraphJson));
  }

  final declarations = parseDeclarations(context, mergedSymbolgraph);
  final transformedDeclarations = transform(
    context,
    declarations,
    filter: config.include,
  );
  final wrapperCode = generate(
    transformedDeclarations,
    importedModuleNames: sourceModules.nonNulls.toList(),
    preamble: config.preamble,
  );

  File.fromUri(config.outputFile).writeAsStringSync(wrapperCode);

  if (deleteTempDirWhenDone) {
    tempDir.deleteSync(recursive: true);
  }
}

Future<void> _generateSymbolgraphJson(
  Command symbolgraphCommand,
  Directory workingDirectory,
) async {
  final result = await Process.run(
    symbolgraphCommand.executable,
    symbolgraphCommand.args,
    workingDirectory: workingDirectory.path,
  );

  if (result.exitCode != 0) {
    throw ProcessException(
      symbolgraphCommand.executable,
      symbolgraphCommand.args,
      'Error generating symbol graph \n${result.stdout} \n${result.stderr}',
    );
  }
}
