// Copyright (c) 2014, 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:collection';

import 'package:analyzer/analyzer.dart' as analyzer;
import 'package:path/path.dart' as p;

import '../ascii_tree.dart' as tree;
import '../command.dart';
import '../dart.dart';
import '../log.dart' as log;
import '../package.dart';
import '../sdk.dart';
import '../utils.dart';

/// Returns `true` if [path] looks like a Dart entrypoint.
bool _isDartExecutable(String path) {
  try {
    var unit = analyzer.parseDartFile(path, parseFunctionBodies: false);
    return isEntrypoint(unit);
  } on analyzer.AnalyzerErrorGroup {
    return false;
  }
}

/// Handles the `deps` pub command.
class DepsCommand extends PubCommand {
  String get name => "deps";
  String get description => "Print package dependencies.";
  List<String> get aliases => const ["dependencies", "tab"];
  String get invocation => "pub deps";
  String get docUrl => "http://dartlang.org/tools/pub/cmd/pub-deps.html";
  bool get takesArguments => false;

  /// The [StringBuffer] used to accumulate the output.
  StringBuffer _buffer;

  /// Whether to include dev dependencies.
  bool get _includeDev => argResults['dev'];

  DepsCommand() {
    argParser.addOption("style",
        abbr: "s",
        help: "How output should be displayed.",
        allowed: ["compact", "tree", "list"],
        defaultsTo: "tree");

    argParser.addFlag("dev",
        negatable: true,
        help: "Whether to include dev dependencies.",
        defaultsTo: true);

    argParser.addFlag("executables",
        negatable: false, help: "List all available executables.");
  }

  void run() {
    // Explicitly run this in case we don't access `entrypoint.packageGraph`.
    entrypoint.assertUpToDate();

    _buffer = new StringBuffer();

    if (argResults['executables']) {
      _outputExecutables();
    } else {
      for (var sdk in sdks.values) {
        if (!sdk.isAvailable) continue;
        _buffer.writeln("${log.bold('${sdk.name} SDK')} ${sdk.version}");
      }

      _buffer.writeln(_labelPackage(entrypoint.root));

      switch (argResults["style"]) {
        case "compact":
          _outputCompact();
          break;
        case "list":
          _outputList();
          break;
        case "tree":
          _outputTree();
          break;
      }
    }

    log.message(_buffer);
  }

  /// Outputs a list of all of the package's immediate, dev, override, and
  /// transitive dependencies.
  ///
  /// For each dependency listed, *that* package's immediate dependencies are
  /// shown. Unlike [_outputList], this prints all of these dependencies on one
  /// line.
  void _outputCompact() {
    var root = entrypoint.root;
    _outputCompactPackages("dependencies", root.dependencies.keys);
    if (_includeDev) {
      _outputCompactPackages("dev dependencies", root.devDependencies.keys);
    }
    _outputCompactPackages(
        "dependency overrides", root.dependencyOverrides.keys);

    var transitive = _getTransitiveDependencies();
    _outputCompactPackages("transitive dependencies", transitive);
  }

  /// Outputs one section of packages in the compact output.
  _outputCompactPackages(String section, Iterable<String> names) {
    if (names.isEmpty) return;

    _buffer.writeln();
    _buffer.writeln("$section:");
    for (var name in ordered(names)) {
      var package = _getPackage(name);

      _buffer.write("- ${_labelPackage(package)}");
      if (package.dependencies.isEmpty) {
        _buffer.writeln();
      } else {
        var depNames = package.dependencies.keys;
        var depsList = "[${depNames.join(' ')}]";
        _buffer.writeln(" ${log.gray(depsList)}");
      }
    }
  }

  /// Outputs a list of all of the package's immediate, dev, override, and
  /// transitive dependencies.
  ///
  /// For each dependency listed, *that* package's immediate dependencies are
  /// shown.
  void _outputList() {
    var root = entrypoint.root;
    _outputListSection("dependencies", root.dependencies.keys);
    if (_includeDev) {
      _outputListSection("dev dependencies", root.devDependencies.keys);
    }
    _outputListSection("dependency overrides", root.dependencyOverrides.keys);

    var transitive = _getTransitiveDependencies();
    if (transitive.isEmpty) return;

    _outputListSection("transitive dependencies", ordered(transitive));
  }

  /// Outputs one section of packages in the list output.
  _outputListSection(String name, Iterable<String> deps) {
    if (deps.isEmpty) return;

    _buffer.writeln();
    _buffer.writeln("$name:");

    for (var name in deps) {
      var package = _getPackage(name);
      _buffer.writeln("- ${_labelPackage(package)}");

      for (var dep in package.dependencies.values) {
        _buffer
            .writeln("  - ${log.bold(dep.name)} ${log.gray(dep.constraint)}");
      }
    }
  }

  /// Generates a dependency tree for the root package.
  ///
  /// If a package is encountered more than once (i.e. a shared or circular
  /// dependency), later ones are not traversed. This is done in breadth-first
  /// fashion so that a package will always be expanded at the shallowest
  /// depth that it appears at.
  void _outputTree() {
    // The work list for the breadth-first traversal. It contains the package
    // being added to the tree, and the parent map that will receive that
    // package.
    var toWalk = new Queue<Pair<Package, Map<String, Map>>>();
    var visited = new Set<String>.from([entrypoint.root.name]);

    // Start with the root dependencies.
    var packageTree = <String, Map>{};
    var immediateDependencies =
        entrypoint.root.immediateDependencies.keys.toSet();
    if (!_includeDev) {
      immediateDependencies.removeAll(entrypoint.root.devDependencies.keys);
    }
    for (var name in immediateDependencies) {
      toWalk.add(new Pair(_getPackage(name), packageTree));
    }

    // Do a breadth-first walk to the dependency graph.
    while (toWalk.isNotEmpty) {
      var pair = toWalk.removeFirst();
      var package = pair.first;
      var map = pair.last;

      if (visited.contains(package.name)) {
        map[log.gray('${package.name}...')] = {};
        continue;
      }

      visited.add(package.name);

      // Populate the map with this package's dependencies.
      var childMap = <String, Map>{};
      map[_labelPackage(package)] = childMap;

      for (var dep in package.dependencies.values) {
        toWalk.add(new Pair(_getPackage(dep.name), childMap));
      }
    }

    _buffer.write(tree.fromMap(packageTree, showAllChildren: true));
  }

  String _labelPackage(Package package) =>
      "${log.bold(package.name)} ${package.version}";

  /// Gets the names of the non-immediate dependencies of the root package.
  Set<String> _getTransitiveDependencies() {
    var transitive = _getAllDependencies();
    var root = entrypoint.root;
    transitive.remove(root.name);
    transitive.removeAll(root.dependencies.keys);
    if (_includeDev) {
      transitive.removeAll(root.devDependencies.keys);
    }
    transitive.removeAll(root.dependencyOverrides.keys);
    return transitive;
  }

  Set<String> _getAllDependencies() {
    if (_includeDev) return entrypoint.packageGraph.packages.keys.toSet();

    var nonDevDependencies = entrypoint.root.dependencies.keys.toList()
      ..addAll(entrypoint.root.dependencyOverrides.keys);
    return nonDevDependencies
        .expand((name) => entrypoint.packageGraph.transitiveDependencies(name))
        .map((package) => package.name)
        .toSet();
  }

  /// Get the package named [name], or throw a [DataError] if it's not
  /// available.
  ///
  /// It's very unlikely that the lockfile won't be up-to-date with the pubspec,
  /// but it's possible, since [Entrypoint.assertUpToDate]'s modification time
  /// check can return a false negative. This fails gracefully if that happens.
  Package _getPackage(String name) {
    var package = entrypoint.packageGraph.packages[name];
    if (package != null) return package;
    dataError('The pubspec.yaml file has changed since the pubspec.lock file '
        'was generated, please run "pub get" again.');
    return null;
  }

  /// Outputs all executables reachable from [entrypoint].
  void _outputExecutables() {
    var packages = []
      ..add(entrypoint.root)
      ..addAll((_includeDev
              ? entrypoint.root.immediateDependencies
              : entrypoint.root.dependencies)
          .keys
          .map((name) => entrypoint.packageGraph.packages[name]));

    for (var package in packages) {
      var executables = _getExecutablesFor(package);
      if (executables.isNotEmpty) {
        _buffer.writeln(_formatExecutables(package.name, executables.toList()));
      }
    }
  }

  /// Lists all Dart files in the `bin` directory of the [package].
  ///
  /// Returns file names without extensions.
  List<String> _getExecutablesFor(Package package) => package.executablePaths
      .where((e) => _isDartExecutable(p.absolute(package.dir, e)))
      .map((e) => p.basenameWithoutExtension(e));

  /// Returns formatted string that lists [executables] for the [packageName].
  /// Examples:
  ///
  ///     _formatExecutables('foo', ['foo'])        // -> 'foo'
  ///     _formatExecutables('foo', ['bar'])        // -> 'foo:bar'
  ///     _formatExecutables('foo', ['bar', 'foo']) // -> 'foo: foo, bar'
  ///
  /// Note the leading space before first executable and sorting order in the
  /// last example.
  String _formatExecutables(String packageName, List<String> executables) {
    if (executables.length == 1) {
      // If executable matches the package name omit the name of executable in
      // the output.
      return executables.first != packageName
          ? '${packageName}:${log.bold(executables.first)}'
          : log.bold(executables.first);
    }

    // Sort executables to make executable that matches the package name to be
    // the first in the list.
    executables.sort((e1, e2) {
      if (e1 == packageName)
        return -1;
      else if (e2 == packageName)
        return 1;
      else
        return e1.compareTo(e2);
    });

    return '${packageName}: ${executables.map(log.bold).join(', ')}';
  }
}
