// Copyright (c) 2012, 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:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';

import 'git.dart' as git;
import 'io.dart';
import 'package_name.dart';
import 'pubspec.dart';
import 'source_registry.dart';
import 'utils.dart';

final _README_REGEXP = new RegExp(r"^README($|\.)", caseSensitive: false);

/// A named, versioned, unit of code and resource reuse.
class Package {
  /// Compares [a] and [b] orders them by name then version number.
  ///
  /// This is normally used as a [Comparator] to pass to sort. This does not
  /// take a package's description or root directory into account, so multiple
  /// distinct packages may order the same.
  static int orderByNameAndVersion(Package a, Package b) {
    var name = a.name.compareTo(b.name);
    if (name != 0) return name;

    return a.version.compareTo(b.version);
  }

  /// The path to the directory containing the package.
  final String dir;

  /// The name of the package.
  String get name {
    if (pubspec.name != null) return pubspec.name;
    if (dir != null) return p.basename(dir);
    return null;
  }

  /// The package's version.
  Version get version => pubspec.version;

  /// The parsed pubspec associated with this package.
  final Pubspec pubspec;

  /// The immediate dependencies this package specifies in its pubspec.
  Map<String, PackageRange> get dependencies => pubspec.dependencies;

  /// The immediate dev dependencies this package specifies in its pubspec.
  Map<String, PackageRange> get devDependencies => pubspec.devDependencies;

  /// The dependency overrides this package specifies in its pubspec.
  Map<String, PackageRange> get dependencyOverrides =>
      pubspec.dependencyOverrides;

  /// All immediate dependencies this package specifies.
  ///
  /// This includes regular, dev dependencies, and overrides.
  Map<String, PackageRange> get immediateDependencies {
    // Make sure to add overrides last so they replace normal dependencies.
    return {}
      ..addAll(dependencies)
      ..addAll(devDependencies)
      ..addAll(dependencyOverrides);
  }

  /// Returns a list of asset ids for all Dart executables in this package's bin
  /// directory.
  List<String> get executablePaths {
    return ordered(listFiles(beneath: "bin", recursive: false))
        .where((executable) => p.extension(executable) == '.dart')
        .map((executable) => p.relative(executable, from: dir))
        .toList();
  }

  /// Returns the path to the README file at the root of the entrypoint, or null
  /// if no README file is found.
  ///
  /// If multiple READMEs are found, this uses the same conventions as
  /// pub.dartlang.org for choosing the primary one: the README with the fewest
  /// extensions that is lexically ordered first is chosen.
  String get readmePath {
    var readmes = listFiles(recursive: false, useGitIgnore: true)
        .map(p.basename)
        .where((entry) => entry.contains(_README_REGEXP));
    if (readmes.isEmpty) return null;

    return p.join(dir, readmes.reduce((readme1, readme2) {
      var extensions1 = ".".allMatches(readme1).length;
      var extensions2 = ".".allMatches(readme2).length;
      var comparison = extensions1.compareTo(extensions2);
      if (comparison == 0) comparison = readme1.compareTo(readme2);
      return (comparison <= 0) ? readme1 : readme2;
    }));
  }

  /// Returns whether or not this package is in a Git repo.
  bool get inGitRepo {
    if (_inGitRepoCache != null) return _inGitRepoCache;

    if (dir == null || !git.isInstalled) {
      _inGitRepoCache = false;
    } else {
      // If the entire package directory is ignored, don't consider it part of a
      // git repo. `git check-ignore` will return a status code of 0 for
      // ignored, 1 for not ignored, and 128 for not a Git repo.
      var result = runProcessSync(git.command, ['check-ignore', '--quiet', '.'],
          workingDir: dir);
      _inGitRepoCache = result.exitCode == 1;
    }

    return _inGitRepoCache;
  }

  bool _inGitRepoCache;

  /// Loads the package whose root directory is [packageDir].
  ///
  /// [name] is the expected name of that package (e.g. the name given in the
  /// dependency), or `null` if the package being loaded is the entrypoint
  /// package.
  Package.load(String name, String packageDir, SourceRegistry sources,
      {bool isRootPackage: false})
      : dir = packageDir,
        pubspec = new Pubspec.load(packageDir, sources,
            expectedName: name, includeDefaultSdkConstraint: !isRootPackage);

  /// Constructs a package with the given pubspec.
  ///
  /// The package will have no directory associated with it.
  Package.inMemory(this.pubspec) : dir = null;

  /// Creates a package with [pubspec] located at [dir].
  Package(this.pubspec, this.dir);

  /// Given a relative path within this package, returns its absolute path.
  ///
  /// This is similar to `p.join(dir, part1, ...)`, except that subclasses may
  /// override it to report that certain paths exist elsewhere than within
  /// [dir].
  String path(String part1,
      [String part2,
      String part3,
      String part4,
      String part5,
      String part6,
      String part7]) {
    if (dir == null) {
      throw new StateError("Package $name is in-memory and doesn't have paths "
          "on disk.");
    }
    return p.join(dir, part1, part2, part3, part4, part5, part6, part7);
  }

  /// Given an absolute path within this package (such as that returned by
  /// [path] or [listFiles]), returns it relative to the package root.
  String relative(String path) {
    if (dir == null) {
      throw new StateError("Package $name is in-memory and doesn't have paths "
          "on disk.");
    }
    return p.relative(path, from: dir);
  }

  /// Returns the type of dependency from this package onto [name].
  DependencyType dependencyType(String name) {
    if (pubspec.fields['dependencies']?.containsKey(name) ?? false) {
      return DependencyType.direct;
    } else if (pubspec.fields['dev_dependencies']?.containsKey(name) ?? false) {
      return DependencyType.dev;
    } else {
      return DependencyType.none;
    }
  }

  /// The basenames of files that are included in [list] despite being hidden.
  static final _WHITELISTED_FILES = const ['.htaccess'];

  /// A set of patterns that match paths to blacklisted files.
  static final _blacklistedFiles = createFileFilter(['pubspec.lock']);

  /// A set of patterns that match paths to blacklisted directories.
  static final _blacklistedDirs = createDirectoryFilter(['packages']);

  /// Returns a list of files that are considered to be part of this package.
  ///
  /// If [beneath] is passed, this will only return files beneath that path,
  /// which is expected to be relative to the package's root directory. If
  /// [recursive] is true, this will return all files beneath that path;
  /// otherwise, it will only return files one level beneath it.
  ///
  /// If [useGitIgnore] is passed, this will take the .gitignore rules into
  /// account if the root directory of the package is (or is contained within) a
  /// Git repository.
  ///
  /// Note that the returned paths won't always be beneath [dir]. To safely
  /// convert them to paths relative to the package root, use [relative].
  List<String> listFiles(
      {String beneath, bool recursive: true, bool useGitIgnore: false}) {
    // An in-memory package has no files.
    if (dir == null) return [];

    if (beneath == null) {
      beneath = dir;
    } else {
      beneath = p.join(dir, beneath);
    }

    if (!dirExists(beneath)) return [];

    // This is used in some performance-sensitive paths and can list many, many
    // files. As such, it leans more havily towards optimization as opposed to
    // readability than most code in pub. In particular, it avoids using the
    // path package, since re-parsing a path is very expensive relative to
    // string operations.
    Iterable<String> files;
    if (useGitIgnore && inGitRepo) {
      // List all files that aren't gitignored, including those not checked in
      // to Git. Use [beneath] as the working dir rather than passing it as a
      // parameter so that we list a submodule using its own git logic.
      files = git.runSync(
          ["ls-files", "--cached", "--others", "--exclude-standard"],
          workingDir: beneath);

      // If we're not listing recursively, strip out paths that contain
      // separators. Since git always prints forward slashes, we always detect
      // them.
      if (!recursive) files = files.where((file) => !file.contains('/'));

      // Git prints files relative to [beneath], but we want them relative to
      // the pub's working directory. It also prints forward slashes on Windows
      // which we normalize away for easier testing.
      //
      // Git lists empty directories as "./", which we skip so we don't keep
      // trying to recurse into the same directory. Normally git doesn't allow
      // totally empty directories, but a submodule that's not checked out
      // behaves like one.
      files = files.where((file) => file != './').map((file) {
        if (Platform.operatingSystem != 'windows') return "$beneath/$file";
        return "$beneath\\${file.replaceAll("/", "\\")}";
      }).expand((file) {
        if (fileExists(file)) return [file];
        if (!dirExists(file)) return [];

        // `git ls-files` only returns files, except in the case of a submodule
        // or a symlink to a directory.
        return recursive ? _listWithinDir(file) : [file];
      });
    } else {
      files = listDir(beneath,
          recursive: recursive,
          includeDirs: false,
          whitelist: _WHITELISTED_FILES);
    }

    return files.where((file) {
      // Using substring here is generally problematic in cases where dir has
      // one or more trailing slashes. If you do listDir("foo"), you'll get back
      // paths like "foo/bar". If you do listDir("foo/"), you'll get "foo/bar"
      // (note the trailing slash was dropped. If you do listDir("foo//"),
      // you'll get "foo//bar".
      //
      // This means if you strip off the prefix, the resulting string may have a
      // leading separator (if the prefix did not have a trailing one) or it may
      // not. However, since we are only using the results of that to call
      // contains() on, the leading separator is harmless.
      assert(file.startsWith(beneath));
      file = file.substring(beneath.length);
      return !_blacklistedFiles.any(file.endsWith) &&
          !_blacklistedDirs.any(file.contains);
    }).toList();
  }

  /// List all files recursively beneath [dir], which should be either a symlink
  /// to a directory or a git submodule.
  ///
  /// This is used by [list] when listing a Git repository, since `git ls-files`
  /// can't natively follow symlinks and (as of Git 2.12.0-rc1) can't use
  /// `--recurse-submodules` in conjunction with `--other`.
  Iterable<String> _listWithinDir(String subdir) {
    assert(dirExists(subdir));
    assert(p.isWithin(dir, subdir));

    var target = new Directory(subdir).resolveSymbolicLinksSync();

    List<String> targetFiles;
    if (p.isWithin(dir, target)) {
      // If the link points within this repo, use git to list the target
      // location so we respect .gitignore.
      targetFiles = listFiles(
          beneath: p.relative(target, from: dir),
          recursive: true,
          useGitIgnore: true);
    } else {
      // If the link points outside this repo, just use the default listing
      // logic.
      targetFiles = listDir(target,
          recursive: true, includeDirs: false, whitelist: _WHITELISTED_FILES);
    }

    // Re-write the paths so they're underneath the symlink.
    return targetFiles.map(
        (targetFile) => p.join(subdir, p.relative(targetFile, from: target)));
  }

  /// Returns a debug string for the package.
  String toString() => '$name $version ($dir)';
}

/// The type of dependency from one package to another.
class DependencyType {
  /// A dependency declared in `dependencies`.
  static const direct = const DependencyType._("direct");

  /// A dependency declared in `dev_dependencies`.
  static const dev = const DependencyType._("dev");

  /// No dependency exists.
  static const none = const DependencyType._("none");

  final String _name;

  const DependencyType._(this._name);

  String toString() => _name;
}
