// Copyright (c) 2019, 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 'dart:typed_data';

import 'package_config_io.dart';

import "errors.dart";
import "package_config_impl.dart";
import "package_config_json.dart";
import "packages_file.dart" as packages_file;
import "util_io.dart" show defaultLoader, pathJoin;

final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json");
final Uri dotPackagesPath = Uri(path: ".packages");
final Uri currentPath = Uri(path: ".");
final Uri parentPath = Uri(path: "..");

/// Discover the package configuration for a Dart script.
///
/// The [baseDirectory] points to the directory of the Dart script.
/// A package resolution strategy is found by going through the following steps,
/// and stopping when something is found.
///
/// * Check if a `.dart_tool/package_config.json` file exists in the directory.
/// * Check if a `.packages` file exists in the directory.
/// * Repeat these checks for the parent directories until reaching the
///   root directory if [recursive] is true.
///
/// If any of these tests succeed, a `PackageConfig` class is returned.
/// Returns `null` if no configuration was found. If a configuration
/// is needed, then the caller can supply [PackageConfig.empty].
Future<PackageConfig?> findPackageConfig(
    Directory baseDirectory, bool recursive, void onError(Object error)) async {
  var directory = baseDirectory;
  if (!directory.isAbsolute) directory = directory.absolute;
  if (!await directory.exists()) {
    return null;
  }
  do {
    // Check for $cwd/.packages
    var packageConfig = await findPackagConfigInDirectory(directory, onError);
    if (packageConfig != null) return packageConfig;
    if (!recursive) break;
    // Check in parent directories.
    var parentDirectory = directory.parent;
    if (parentDirectory.path == directory.path) break;
    directory = parentDirectory;
  } while (true);
  return null;
}

/// Similar to [findPackageConfig] but based on a URI.
Future<PackageConfig?> findPackageConfigUri(
    Uri location,
    Future<Uint8List?> loader(Uri uri)?,
    void onError(Object error),
    bool recursive) async {
  if (location.isScheme("package")) {
    onError(PackageConfigArgumentError(
        location, "location", "Must not be a package: URI"));
    return null;
  }
  if (loader == null) {
    if (location.isScheme("file")) {
      return findPackageConfig(
          Directory.fromUri(location.resolveUri(currentPath)),
          recursive,
          onError);
    }
    loader = defaultLoader;
  }
  if (!location.path.endsWith("/")) location = location.resolveUri(currentPath);
  while (true) {
    var file = location.resolveUri(packageConfigJsonPath);
    var bytes = await loader(file);
    if (bytes != null) {
      return parsePackageConfigBytes(bytes, file, onError);
    }
    file = location.resolveUri(dotPackagesPath);
    bytes = await loader(file);
    if (bytes != null) {
      return packages_file.parse(bytes, file, onError);
    }
    if (!recursive) break;
    var parent = location.resolveUri(parentPath);
    if (parent == location) break;
    location = parent;
  }
  return null;
}

/// Finds a `.packages` or `.dart_tool/package_config.json` file in [directory].
///
/// Loads the file, if it is there, and returns the resulting [PackageConfig].
/// Returns `null` if the file isn't there.
/// Reports a [FormatException] if a file is there but the content is not valid.
/// If the file exists, but fails to be read, the file system error is reported.
///
/// If [onError] is supplied, parsing errors are reported using that, and
/// a best-effort attempt is made to return a package configuration.
/// This may be the empty package configuration.
Future<PackageConfig?> findPackagConfigInDirectory(
    Directory directory, void onError(Object error)) async {
  var packageConfigFile = await checkForPackageConfigJsonFile(directory);
  if (packageConfigFile != null) {
    return await readPackageConfigJsonFile(packageConfigFile, onError);
  }
  packageConfigFile = await checkForDotPackagesFile(directory);
  if (packageConfigFile != null) {
    return await readDotPackagesFile(packageConfigFile, onError);
  }
  return null;
}

Future<File?> checkForPackageConfigJsonFile(Directory directory) async {
  assert(directory.isAbsolute);
  var file =
      File(pathJoin(directory.path, ".dart_tool", "package_config.json"));
  if (await file.exists()) return file;
  return null;
}

Future<File?> checkForDotPackagesFile(Directory directory) async {
  var file = File(pathJoin(directory.path, ".packages"));
  if (await file.exists()) return file;
  return null;
}
