// Copyright (c) 2022, 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:package_config/package_config.dart';

import 'find_sdk_root.dart';
import 'suite.dart';

/// Writes a package config under [root] and returns the [Uri] pointing to it.
Future<Uri> writePackageConfig(
    Module module, Set<Module> transitiveDependencies, Uri root,
    {bool useRealPaths = false}) async {
  const packageConfigJsonPath = ".dart_tool/package_config.json";
  var sdkRoot = await findRoot();
  Uri packageConfigUri = sdkRoot.resolve(packageConfigJsonPath);
  var packageConfig = await loadPackageConfigUri(packageConfigUri);

  // We create a package_config.json file to support the CFE in (a) determine
  // the default nullability if the current module is a package, and (b)
  // resolve `package:` imports. Technically the latter shouldn't be necessary,
  // but the CFE requires that if a `package:` URI of a dependency is used in an
  // import, then we need that package entry in the associated file. In fact,
  // after it checks that the definition exists, the CFE will not actually use
  // the resolved URI if a library for the import URI is already found in one of
  // the provide .dill files of the dependencies. For that reason, and to ensure
  // that a step only has access to the files provided in a module, we generate
  // a config file with invalid folders for other packages.
  // TODO(sigmund): follow up with the CFE to see if we can remove the need
  // for these dummy entries.
  var packagesJson = [];
  if (module.isPackage) {
    packagesJson.add(_packageConfigEntry(
        module.name, Uri.parse('../${module.packageBase}')));
  }

  int unusedNum = 0;
  for (Module dependency in transitiveDependencies) {
    if (dependency.isPackage) {
      // rootUri should be ignored for dependent modules, so we pass in a
      // bogus value.
      var rootUri =
          useRealPaths ? dependency.rootUri : Uri.parse('unused${unusedNum++}');

      var dependentPackage = packageConfig[dependency.name];
      var packageJson = dependentPackage == null
          ? _packageConfigEntry(dependency.name, rootUri,
              packageRoot: dependency.packageBase)
          : _packageConfigEntry(dependentPackage.name, rootUri,
              packageRoot: dependency.packageBase,
              version: dependentPackage.languageVersion);
      packagesJson.add(packageJson);
    }
  }

  var packageConfigFile = File.fromUri(root.resolve(packageConfigJsonPath));
  await packageConfigFile.create(recursive: true);
  await packageConfigFile.writeAsString('{'
      '  "configVersion": ${packageConfig.version},'
      '  "packages": [ ${packagesJson.join(',')} ]'
      '}');
  return packageConfigFile.uri;
}

String _packageConfigEntry(String name, Uri root,
    {Uri? packageRoot, LanguageVersion? version}) {
  var fields = [
    '"name": "$name"',
    '"rootUri": "$root"',
    if (packageRoot != null) '"packageUri": "$packageRoot"',
    if (version != null) '"languageVersion": "$version"'
  ];
  return '{${fields.join(',')}}';
}
