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