// 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:code_assets/code_assets.dart';
import 'package:dartdev/src/native_assets_bundling.dart';
import 'package:dartdev/src/sdk.dart';
import 'package:dartdev/src/utils.dart';
import 'package:data_assets/data_assets.dart';
import 'package:file/local.dart';
import 'package:hooks/hooks.dart';
import 'package:hooks_runner/hooks_runner.dart';
import 'package:logging/logging.dart';
import 'package:package_config/package_config.dart' as package_config;
import 'package:yaml/yaml.dart' show loadYaml;

import 'core.dart';

class DartNativeAssetsBuilder {
  final Uri? pubspecUri;
  final Uri packageConfigUri;
  final package_config.PackageConfig packageConfig;
  final String runPackageName;
  final bool verbose;

  static const _fileSystem = LocalFileSystem();

  late final Future<PackageLayout> _packageLayout = () async {
    return PackageLayout.fromPackageConfig(
      _fileSystem,
      packageConfig,
      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,
      userDefines: UserDefines(workspacePubspec: pubspecUri),
    );
  }();

  DartNativeAssetsBuilder({
    this.pubspecUri,
    required this.packageConfigUri,
    required this.packageConfig,
    required this.runPackageName,
    required this.verbose,
    Target? target,
  }) : target = target ?? Target.current;

  /// 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,
      outputUri,
      relocatable: false,
    );

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

  Future<bool> warnOnNativeAssets() async {
    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`.',
    );
    return true;
  }

  late final _extensions = [
    CodeAssetExtension(
      targetOS: target.os,
      linkModePreference: LinkModePreference.dynamic,
      targetArchitecture: target.architecture,
      macOS: _macOSConfig,
      cCompiler: _cCompilerConfig,
    ),
    // TODO(dacoharkes,mosum): This should be gated behind a data-assets
    // experiment flag.
    DataAssetsExtension(),
  ];

  Future<BuildResult?> _buildNativeAssetsShared({
    required bool linkingEnabled,
  }) async {
    final builder = await _nativeAssetsBuildRunner;
    final buildResult = await builder.build(
      extensions: _extensions,
      linkingEnabled: linkingEnabled,
    );
    if (buildResult.isFailure) return null;
    return buildResult.success;
  }

  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(
      extensions: _extensions,
      resourceIdentifiers:
          recordedUsagesPath != null ? Uri.file(recordedUsagesPath) : null,
      buildResult: buildResult,
    );
    if (linkResult.isFailure) return null;
    return linkResult.success;
  }

  final Target target;

  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;
  }

  /// Tries to load the package config.
  ///
  /// Returns null and writes to stderr if the package config is malformed.
  static Future<package_config.PackageConfig?> loadPackageConfig(
      Uri packageConfigUri) async {
    try {
      return await package_config.loadPackageConfigUri(packageConfigUri);
    } 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 '
        '${packageConfigUri.toFilePath()}: ${e.message}.',
      );
      return null;
    }
  }

  /// 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 packageConfig =
          File.fromUri(uri.resolve('.dart_tool/package_config.json'));
      final packageGraph =
          File.fromUri(uri.resolve('.dart_tool/package_graph.json'));
      if (await packageConfig.exists() && await packageGraph.exists()) {
        return packageConfig.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;
    }
  }

  static Future<Uri?> findWorkspacePubspec(Uri? workspacePackageConfig) async {
    if (workspacePackageConfig == null) {
      return null;
    }
    final candidate = workspacePackageConfig.resolve('../pubspec.yaml');
    if (File.fromUri(candidate).existsSync()) {
      return candidate;
    }
    return null;
  }

  /// 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 pubspecUri = await findPubspec(uri);
    if (pubspecUri == null) {
      return null;
    }
    final pubspecFile = File.fromUri(pubspecUri);
    final contents = await pubspecFile.readAsString();
    final pubspec = loadYaml(contents);
    return pubspec['name'];
  }
}
