// 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.

/// A simple library for rendering a list of files as a directory tree.
library pub.directory_tree;

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

import 'utils.dart';

/// Draws a directory tree for the given list of files. Given a list of files
/// like:
///
///     TODO
///     example/console_example.dart
///     example/main.dart
///     example/web copy/web_example.dart
///     test/absolute_test.dart
///     test/basename_test.dart
///     test/dirname_test.dart
///     test/extension_test.dart
///     test/is_absolute_test.dart
///     test/is_relative_test.dart
///     test/join_test.dart
///     test/normalize_test.dart
///     test/relative_test.dart
///     test/split_test.dart
///     .gitignore
///     README.md
///     lib/path.dart
///     pubspec.yaml
///     test/all_test.dart
///     test/path_posix_test.dart
///     test/path_windows_test.dart
///
/// this will render:
///
///     |-- .gitignore
///     |-- README.md
///     |-- TODO
///     |-- example
///     |   |-- console_example.dart
///     |   |-- main.dart
///     |   '-- web copy
///     |       '-- web_example.dart
///     |-- lib
///     |   '-- path.dart
///     |-- pubspec.yaml
///     '-- test
///         |-- absolute_test.dart
///         |-- all_test.dart
///         |-- basename_test.dart
///         | (7 more...)
///         |-- path_windows_test.dart
///         |-- relative_test.dart
///         '-- split_test.dart
///
/// If [baseDir] is passed, it will be used as the root of the tree.
String generateTree(List<String> files, {String baseDir}) {
  // Parse out the files into a tree of nested maps.
  var root = {};
  for (var file in files) {
    if (baseDir != null) file = path.relative(file, from: baseDir);
    var parts = path.split(file);
    var directory = root;
    for (var part in path.split(file)) {
      directory = directory.putIfAbsent(part, () => {});
    }
  }

  // Walk the map recursively and render to a string.
  var buffer = new StringBuffer();
  _draw(buffer, '', false, null, root);
  return buffer.toString();
}

void _drawLine(StringBuffer buffer, String prefix, bool isLastChild,
               String name) {
  // Print lines.
  buffer.write(prefix);
  if (name != null) {
    if (isLastChild) {
      buffer.write("'-- ");
    } else {
      buffer.write("|-- ");
    }
  }

  // Print name.
  buffer.writeln(name);
}

String _getPrefix(bool isRoot, bool isLast) {
  if (isRoot) return "";
  if (isLast) return "    ";
  return "|   ";
}

void _draw(StringBuffer buffer, String prefix, bool isLast,
                 String name, Map children) {
  // Don't draw a line for the root node.
  if (name != null) _drawLine(buffer, prefix, isLast, name);

  // Recurse to the children.
  var childNames = ordered(children.keys);

  _drawChild(bool isLastChild, String child) {
    var childPrefix = _getPrefix(name == null, isLast);
    _draw(buffer, '$prefix$childPrefix', isLastChild, child, children[child]);
  }

  if (name == null || childNames.length <= 10) {
    // Not too many, so show all the children.
    for (var i = 0; i < childNames.length; i++) {
      _drawChild(i == childNames.length - 1, childNames[i]);
    }
  } else {
    // Show the first few.
    _drawChild(false, childNames[0]);
    _drawChild(false, childNames[1]);
    _drawChild(false, childNames[2]);

    // Elide the middle ones.
    buffer.write(prefix);
    buffer.write(_getPrefix(name == null, isLast));
    buffer.writeln('| (${childNames.length - 6} more...)');

    // Show the last few.
    _drawChild(false, childNames[childNames.length - 3]);
    _drawChild(false, childNames[childNames.length - 2]);
    _drawChild(true, childNames[childNames.length - 1]);
  }
}
