// 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:async';
import 'dart:io';

import 'package:dartdev/src/native_assets_bundling.dart';
import 'package:dartdev/src/sdk.dart';
import 'package:dartdev/src/utils.dart';
import 'package:file/local.dart';
import 'package:logging/logging.dart';
import 'package:native_assets_builder/native_assets_builder.dart';
import 'package:native_assets_cli/code_assets_builder.dart';
import 'package:native_assets_cli/data_assets_builder.dart';
import 'package:package_config/package_config.dart' as package_config;

import 'core.dart';

class DartNativeAssetsBuilder {
  final Uri packageConfigUri;
  final String runPackageName;
  final bool verbose;

  static const _fileSystem = LocalFileSystem();

  late final Future<PackageLayout> _packageLayout = () async {
    return PackageLayout.fromPackageConfig(
      _fileSystem,
      await package_config.loadPackageConfigUri(packageConfigUri),
      packageConfigUri,
      runPackageName,
    );
  }();

  late final _logger = Logger('')
    ..onRecord.listen((LogRecord record) {
      final levelValue = record.level.value;
      if (levelValue >= Level.SEVERE.value) {
        log.stderr(record.message);
      } else if (levelValue >= Level.WARNING.value ||
          verbose && levelValue >= Level.INFO.value) {
        log.stdout(record.message);
      } else {
        // Note, this is ignored by default.
        log.trace(record.message);
      }
    });

  late final Future<NativeAssetsBuildRunner> _nativeAssetsBuildRunner =
      () async {
    return NativeAssetsBuildRunner(
      // This always runs in JIT mode.
      dartExecutable: Uri.file(sdk.dart),
      logger: _logger,
      fileSystem: const LocalFileSystem(),
      packageLayout: await _packageLayout,
    );
  }();

  DartNativeAssetsBuilder({
    required this.packageConfigUri,
    required this.runPackageName,
    required this.verbose,
  });

  /// Compiles all native assets for host OS in JIT mode.
  ///
  /// If provided, only native assets of all transitive dependencies of
  /// [runPackageName] are built.
  Future<List<EncodedAsset>?> compileNativeAssetsJit() async {
    final buildResult = await _buildNativeAssetsShared(linkingEnabled: false);
    if (buildResult == null) return null;
    return buildResult.encodedAssets;
  }

  /// Compiles all native assets for host OS in JIT mode, and creates the
  /// native assets yaml file.
  ///
  /// If provided, only native assets of all transitive dependencies of
  /// [runPackageName] are built.
  ///
  /// Used in `dart run` and `dart test`.
  Future<Uri?> compileNativeAssetsJitYamlFile() async {
    final assets = await compileNativeAssetsJit();
    if (assets == null) return null;

    final dartToolUri = Directory.current.uri.resolve('.dart_tool/');
    final outputUri = dartToolUri.resolve('native_assets/');
    await Directory.fromUri(outputUri).create(recursive: true);

    final kernelAssets = await bundleNativeAssets(
      assets,
      Target.current,
      outputUri,
      relocatable: false,
    );

    return await writeNativeAssetsYaml(
      kernelAssets,
      dartToolUri,
      header: '''# Native assets mapping for host OS in JIT mode.
# Generated by dartdev and package:native_assets_builder.
''',
    );
  }

  Future<bool> warnOnNativeAssets() async {
    try {
      final builder = await _nativeAssetsBuildRunner;
      final packageNames = await builder.packagesWithBuildHooks();
      if (packageNames.isEmpty) return false;
      log.stderr(
        'Package(s) $packageNames require the native assets feature to be enabled. '
        'Enable native assets with `--enable-experiment=native-assets`.',
      );
    } on FormatException catch (e) {
      // This can be thrown if the package_config.json is malformed or has
      // duplicate entries.
      log.stderr(
        'Error encountered while parsing package_config.json: ${e.message}',
      );
    }
    return true;
  }

  Future<BuildResult?> _buildNativeAssetsShared({
    required bool linkingEnabled,
  }) async {
    final builder = await _nativeAssetsBuildRunner;
    final buildResult = await builder.build(
      inputCreator: () => BuildInputBuilder()
        ..config.setupCode(
          targetOS: target.os,
          linkModePreference: LinkModePreference.dynamic,
          targetArchitecture: target.architecture,
          macOS: _macOSConfig,
          cCompiler: _cCompilerConfig,
        ),
      inputValidator: (config) async => [
        ...await validateDataAssetBuildInput(config),
        ...await validateCodeAssetBuildInput(config),
      ],
      linkingEnabled: linkingEnabled,
      buildAssetTypes: [
        CodeAsset.type,
      ],
      buildValidator: (config, output) async => [
        ...await validateDataAssetBuildOutput(config, output),
        ...await validateCodeAssetBuildOutput(config, output),
      ],
      applicationAssetValidator: (assets) async => [
        ...await validateCodeAssetInApplication(assets),
      ],
    );
    return buildResult;
  }

  Future<BuildResult?> buildNativeAssetsAOT() {
    return _buildNativeAssetsShared(linkingEnabled: true);
  }

  Future<LinkResult?> linkNativeAssetsAOT({
    required String? recordedUsagesPath,
    required BuildResult buildResult,
  }) async {
    final builder = await _nativeAssetsBuildRunner;
    final linkResult = await builder.link(
      inputCreator: () => LinkInputBuilder()
        ..config.setupCode(
          targetOS: target.os,
          targetArchitecture: target.architecture,
          linkModePreference: LinkModePreference.dynamic,
          macOS: _macOSConfig,
          cCompiler: _cCompilerConfig,
        ),
      inputValidator: (config) async => [
        ...await validateDataAssetLinkInput(config),
        ...await validateCodeAssetLinkInput(config),
      ],
      resourceIdentifiers:
          recordedUsagesPath != null ? Uri.file(recordedUsagesPath) : null,
      buildResult: buildResult,
      buildAssetTypes: [
        CodeAsset.type,
      ],
      linkValidator: (config, output) async => [
        ...await validateDataAssetLinkOutput(config, output),
        ...await validateCodeAssetLinkOutput(config, output),
      ],
      applicationAssetValidator: (assets) async => [
        ...await validateCodeAssetInApplication(assets),
      ],
    );
    return linkResult;
  }

  /// Dart does not do cross compilation. Target is always host.
  late final target = Target.current;

  late final _macOSConfig = target.os == OS.macOS
      ? MacOSCodeConfig(targetVersion: minimumSupportedMacOSVersion)
      : null;

  late final _cCompilerConfig = _getCCompilerConfig(target.os);

  CCompilerConfig? _getCCompilerConfig(OS targetOS) {
    // Specifically for running our tests on Dart CI with the test runner, we
    // recognize specific variables to setup the C Compiler configuration.
    final env = Platform.environment;
    final cc = env['DART_HOOK_TESTING_C_COMPILER__CC'];
    final ar = env['DART_HOOK_TESTING_C_COMPILER__AR'];
    final ld = env['DART_HOOK_TESTING_C_COMPILER__LD'];
    final envScript = env['DART_HOOK_TESTING_C_COMPILER__ENV_SCRIPT'];
    final envScriptArgs =
        env['DART_HOOK_TESTING_C_COMPILER__ENV_SCRIPT_ARGUMENTS']
            ?.split(' ')
            .map((arg) => arg.trim())
            .where((arg) => arg.isNotEmpty)
            .toList();
    if (cc != null && ar != null && ld != null) {
      return CCompilerConfig(
        archiver: Uri.file(ar),
        compiler: Uri.file(cc),
        linker: Uri.file(ld),
        windows: targetOS == OS.windows
            ? WindowsCCompilerConfig(
                developerCommandPrompt: envScript == null
                    ? null
                    : DeveloperCommandPrompt(
                        script: Uri.file(envScript),
                        arguments: envScriptArgs ?? [],
                      ),
              )
            : null,
      );
    }
    return null;
  }

  /// Runs `pub get` if no package config can be found.
  ///
  /// Returns `null` if no package config can be found, even after pub get.
  static Future<Uri?> ensurePackageConfig(Uri uri) async {
    var packageConfig = await _findPackageConfigUri(uri);
    // TODO(https://github.com/dart-lang/package_config/issues/126): Use
    // package config resolution from package:package_config.
    if (packageConfig == null) {
      final pubspecMaybe = await _findPubspec(uri);
      if (pubspecMaybe != null) {
        // Silently run `pub get`, this is what would happen in
        // `getExecutableForCommand` later.
        final result = await Process.run(sdk.dart, ['pub', 'get']);
        if (result.exitCode != 0) {
          return null;
        }
        packageConfig = await _findPackageConfigUri(uri);
      } else {
        return null;
      }
    }
    return packageConfig;
  }

  /// Finds the package config uri.
  ///
  /// Returns `null` if no package config can be found.
  // TODO(https://github.com/dart-lang/package_config/issues/126): Expose this
  // logic in package:package_config.
  static Future<Uri?> _findPackageConfigUri(Uri uri) async {
    while (true) {
      final candidate = uri.resolve('.dart_tool/package_config.json');
      final file = File.fromUri(candidate);
      if (await file.exists()) {
        return file.uri;
      }
      final parent = uri.resolve('..');
      if (parent == uri) {
        return null;
      }
      uri = parent;
    }
  }

  static Future<Uri?> _findPubspec(Uri uri) async {
    while (true) {
      final candidate = uri.resolve('pubspec.yaml');
      if (await File.fromUri(candidate).exists()) {
        return candidate;
      }
      final parent = uri.resolve('..');
      if (parent == uri) {
        return null;
      }
      uri = parent;
    }
  }

  /// Tries to find the package name that [uri] is in.
  ///
  /// Returns `null` if package cannnot be determined.
  static Future<String?> findRootPackageName(Uri uri) async {
    final pubspec = await _findPubspec(uri);
    if (pubspec == null) {
      return null;
    }
    return pubspec.resolve('./').pathSegments.lastWhere((e) => e.isNotEmpty);
  }
}
