// 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 includeDevDependencies;
  final bool verbose;

  static const _fileSystem = LocalFileSystem();

  late final Future<PackageLayout> _packageLayout = () async {
    return PackageLayout.fromPackageConfig(
      _fileSystem,
      packageConfig,
      packageConfigUri,
      runPackageName,
      includeDevDependencies: includeDevDependencies,
    );
  }();

  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.includeDevDependencies,
    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'];
  }
}
