// 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:async';

import 'package:async/async.dart';
import 'package:file/file.dart';
import 'package:path/path.dart' as p;

import 'ast.dart';
import 'utils.dart';

/// The errno for a file or directory not existing on Mac and Linux.
const _enoent = 2;

/// Another errno we see on Windows when trying to list a non-existent
/// directory.
const _enoentWin = 3;

/// A structure built from a glob that efficiently lists filesystem entities
/// that match that glob.
///
/// This structure is designed to list the minimal number of physical
/// directories necessary to find everything that matches the glob. For example,
/// for the glob `foo/{bar,baz}/*`, there's no need to list the working
/// directory or even `foo/`; only `foo/bar` and `foo/baz` should be listed.
///
/// This works by creating a tree of [_ListTreeNode]s, each of which corresponds
/// to a single of directory nesting in the source glob. Each node has child
/// nodes associated with globs ([_ListTreeNode.children]), as well as its own
/// glob ([_ListTreeNode._validator]) that indicates which entities within that
/// node's directory should be returned.
///
/// For example, the glob `foo/{*.dart,b*/*.txt}` creates the following tree:
///
///     .
///     '-- "foo" (validator: "*.dart")
///         '-- "b*" (validator: "*.txt"
///
/// If a node doesn't have a validator, we know we don't have to list it
/// explicitly.
///
/// Nodes can also be marked as "recursive", which means they need to be listed
/// recursively (usually to support `**`). In this case, they will have no
/// children; instead, their validator will just encompass the globs that would
/// otherwise be in their children. For example, the glob
/// `foo/{**.dart,bar/*.txt}` creates a recursive node for `foo` with the
/// validator `**.dart,bar/*.txt`.
///
/// If the glob contains multiple filesystem roots (e.g. `{C:/,D:/}*.dart`),
/// each root will have its own tree of nodes. Relative globs use `.` as their
/// root instead.
class ListTree {
  /// A map from filesystem roots to the list tree for those roots.
  ///
  /// A relative glob will use `.` as its root.
  final Map<String, _ListTreeNode> _trees;

  /// Whether paths listed might overlap.
  ///
  /// If they do, we need to filter out overlapping paths.
  final bool _canOverlap;

  /// The file system to operate on.
  final FileSystem _fileSystem;

  ListTree._(this._trees, this._fileSystem)
      : _canOverlap = _computeCanOverlap(_trees);

  factory ListTree(AstNode glob, FileSystem fileSystem) {
    // The first step in constructing a tree from the glob is to simplify the
    // problem by eliminating options. [glob.flattenOptions] bubbles all options
    // (and certain ranges) up to the top level of the glob so we can deal with
    // them one at a time.
    var options = glob.flattenOptions();
    var trees = <String, _ListTreeNode>{};

    for (var option in options.options) {
      // Since each option doesn't include its own options, we can safely split
      // it into path components.
      var components = option.split(p.context);
      var firstNode = components.first.nodes.first;
      var root = '.';

      // Determine the root for this option, if it's absolute. If it's not, the
      // root's just ".".
      if (firstNode is LiteralNode) {
        var text = firstNode.text;
        // Platform agnostic way of checking for Windows without `dart:io`.
        if (p.context == p.windows) text.replaceAll('/', '\\');
        if (p.isAbsolute(text)) {
          // If the path is absolute, the root should be the only thing in the
          // first component.
          assert(components.first.nodes.length == 1);
          root = firstNode.text;
          components.removeAt(0);
        }
      }

      _addGlob(root, components, trees);
    }

    return ListTree._(trees, fileSystem);
  }

  /// Add the glob represented by [components] to the tree under [root].
  static void _addGlob(String root, List<SequenceNode> components,
      Map<String, _ListTreeNode> trees) {
    // The first [parent] represents the root directory itself. It may be null
    // here if this is the first option with this particular [root]. If so,
    // we'll create it below.
    //
    // As we iterate through [components], [parent] will be set to
    // progressively more nested nodes.
    var parent = trees[root];
    for (var i = 0; i < components.length; i++) {
      var component = components[i];
      var recursive = component.nodes.any((node) => node is DoubleStarNode);
      var complete = i == components.length - 1;

      // If the parent node for this level of nesting already exists, the new
      // option will be added to it as additional validator options and/or
      // additional children.
      //
      // If the parent doesn't exist, we'll create it in one of the else
      // clauses below.
      if (parent != null) {
        if (parent.isRecursive || recursive) {
          // If [component] is recursive, mark [parent] as recursive. This
          // will cause all of its children to be folded into its validator.
          // If [parent] was already recursive, this is a no-op.
          parent.makeRecursive();

          // Add [component] and everything nested beneath it as an option to
          // [parent]. Since [parent] is recursive, it will recursively list
          // everything beneath it and filter them with one big glob.
          parent.addOption(_join(components.sublist(i)));
          return;
        } else if (complete) {
          // If [component] is the last component, add it to [parent]'s
          // validator but not to its children.
          parent.addOption(component);
        } else {
          // On the other hand if there are more components, add [component]
          // to [parent]'s children and not its validator. Since we process
          // each option's components separately, the same component is never
          // both a validator and a child.
          var children = parent.children!;
          if (!children.containsKey(component)) {
            children[component] = _ListTreeNode();
          }
          parent = children[component];
        }
      } else if (recursive) {
        trees[root] = _ListTreeNode.recursive(_join(components.sublist(i)));
        return;
      } else if (complete) {
        trees[root] = _ListTreeNode()..addOption(component);
      } else {
        var rootNode = _ListTreeNode();
        trees[root] = rootNode;
        var rootChildren = rootNode.children!;
        rootChildren[component] = _ListTreeNode();
        parent = rootChildren[component];
      }
    }
  }

  /// Computes the value for [_canOverlap].
  static bool _computeCanOverlap(Map<String, _ListTreeNode> trees) {
    // If this can list a relative path and an absolute path, the former may be
    // contained within the latter.
    if (trees.length > 1 && trees.containsKey('.')) return true;

    // Otherwise, this can only overlap if the tree beneath any given root could
    // overlap internally.
    return trees.values.any((node) => node.canOverlap);
  }

  /// List all entities that match this glob beneath [root].
  Stream<FileSystemEntity> list({String? root, bool followLinks = true}) {
    root ??= '.';
    var group = StreamGroup<FileSystemEntity>();
    for (var rootDir in _trees.keys) {
      var dir = rootDir == '.' ? root : rootDir;
      group.add(
          _trees[rootDir]!.list(dir, _fileSystem, followLinks: followLinks));
    }
    group.close();

    if (!_canOverlap) return group.stream;

    // TODO: Rather than filtering here, avoid double-listing directories
    // in the first place.
    var seen = <String>{};
    return group.stream.where((entity) => seen.add(entity.path));
  }

  /// Synchronosuly list all entities that match this glob beneath [root].
  List<FileSystemEntity> listSync({String? root, bool followLinks = true}) {
    root ??= '.';
    var result = _trees.keys.expand((rootDir) {
      var dir = rootDir == '.' ? root! : rootDir;
      return _trees[rootDir]!
          .listSync(dir, _fileSystem, followLinks: followLinks);
    });

    if (!_canOverlap) return result.toList();

    // TODO: Rather than filtering here, avoid double-listing directories
    // in the first place.
    var seen = <String>{};
    return result.where((entity) => seen.add(entity.path)).toList();
  }
}

/// A single node in a [ListTree].
class _ListTreeNode {
  /// This node's child nodes, by their corresponding globs.
  ///
  /// Each child node will only be listed on directories that match its glob.
  ///
  /// This may be `null`, indicating that this node should be listed
  /// recursively.
  Map<SequenceNode, _ListTreeNode>? children;

  /// This node's validator.
  ///
  /// This determines which entities will ultimately be emitted when [list] is
  /// called.
  OptionsNode? _validator;

  /// Whether this node is recursive.
  ///
  /// A recursive node has no children and is listed recursively.
  bool get isRecursive => children == null;

  bool get _caseSensitive {
    if (_validator != null) return _validator!.caseSensitive;
    if (children?.isEmpty != false) return true;
    return children!.keys.first.caseSensitive;
  }

  /// Whether this node doesn't itself need to be listed.
  ///
  /// If a node has no validator and all of its children are literal filenames,
  /// there's no need to list its contents. We can just directly traverse into
  /// its children.
  bool get _isIntermediate {
    if (_validator != null) return false;
    return children!.keys.every((sequence) =>
        sequence.nodes.length == 1 && sequence.nodes.first is LiteralNode);
  }

  /// Returns whether listing this node might return overlapping results.
  bool get canOverlap {
    // A recusive node can never overlap with itself, because it will only ever
    // involve a single call to [Directory.list] that's then filtered with
    // [_validator].
    if (isRecursive) return false;

    // If there's more than one child node and at least one of the children is
    // dynamic (that is, matches more than just a literal string), there may be
    // overlap.
    if (children!.length > 1) {
      // Case-insensitivity means that even literals may match multiple entries.
      if (!_caseSensitive) return true;

      if (children!.keys.any((sequence) =>
          sequence.nodes.length > 1 || sequence.nodes.single is! LiteralNode)) {
        return true;
      }
    }

    return children!.values.any((node) => node.canOverlap);
  }

  /// Creates a node with no children and no validator.
  _ListTreeNode()
      : children = <SequenceNode, _ListTreeNode>{},
        _validator = null;

  /// Creates a recursive node the given [validator].
  _ListTreeNode.recursive(SequenceNode validator)
      : children = null,
        _validator =
            OptionsNode([validator], caseSensitive: validator.caseSensitive);

  /// Transforms this into recursive node, folding all its children into its
  /// validator.
  void makeRecursive() {
    if (isRecursive) return;
    var children = this.children!;
    _validator = OptionsNode(children.entries.map((entry) {
      entry.value.makeRecursive();
      return _join([entry.key, entry.value._validator!]);
    }), caseSensitive: _caseSensitive);
    this.children = null;
  }

  /// Adds [validator] to this node's existing validator.
  void addOption(SequenceNode validator) {
    if (_validator == null) {
      _validator =
          OptionsNode([validator], caseSensitive: validator.caseSensitive);
    } else {
      _validator!.options.add(validator);
    }
  }

  /// Lists all entities within [dir] matching this node or its children.
  ///
  /// This may return duplicate entities. These will be filtered out in
  /// [ListTree.list].
  Stream<FileSystemEntity> list(String dir, FileSystem fileSystem,
      {bool followLinks = true}) {
    if (isRecursive) {
      return fileSystem
          .directory(dir)
          .list(recursive: true, followLinks: followLinks)
          .where((entity) => _matches(p.relative(entity.path, from: dir)));
    }

    // Don't spawn extra [Directory.list] calls when we already know exactly
    // which subdirectories we're interested in.
    if (_isIntermediate && _caseSensitive) {
      var resultGroup = StreamGroup<FileSystemEntity>();
      children!.forEach((sequence, child) {
        resultGroup.add(child.list(
            p.join(dir, (sequence.nodes.single as LiteralNode).text),
            fileSystem,
            followLinks: followLinks));
      });
      resultGroup.close();
      return resultGroup.stream;
    }

    return StreamCompleter.fromFuture(() async {
      var entities = await fileSystem
          .directory(dir)
          .list(followLinks: followLinks)
          .toList();
      await _validateIntermediateChildrenAsync(dir, entities, fileSystem);

      var resultGroup = StreamGroup<FileSystemEntity>();
      var resultController = StreamController<FileSystemEntity>(sync: true);
      // TODO: Remove `??` workaround once 2.15 ships (which allows null).
      unawaited(resultGroup.add(resultController.stream) ?? Future.value());
      for (var entity in entities) {
        var basename = p.relative(entity.path, from: dir);
        if (_matches(basename)) resultController.add(entity);

        children!.forEach((sequence, child) {
          if (entity is! Directory) return;
          if (!sequence.matches(basename)) return;
          var stream = child
              .list(p.join(dir, basename), fileSystem, followLinks: followLinks)
              .handleError((_) {}, test: (error) {
            // Ignore errors from directories not existing. We do this here so
            // that we only ignore warnings below wild cards. For example, the
            // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but
            // succeed if "foo/bar/qux/baz" doesn't exist.
            return error is FileSystemException &&
                (error.osError!.errorCode == _enoent ||
                    error.osError!.errorCode == _enoentWin);
          });
          resultGroup.add(stream);
        });
      }
      unawaited(resultController.close());
      unawaited(resultGroup.close());
      return resultGroup.stream;
    }());
  }

  /// If this is a case-insensitive list, validates that all intermediate
  /// children (according to [_isIntermediate]) match at least one entity in
  /// [entities].
  ///
  /// This ensures that listing "foo/bar/*" fails on case-sensitive systems if
  /// "foo/bar" doesn't exist.
  Future _validateIntermediateChildrenAsync(String dir,
      List<FileSystemEntity> entities, FileSystem fileSystem) async {
    if (_caseSensitive) return;

    for (var entry in children!.entries) {
      var child = entry.value;
      var sequence = entry.key;
      if (!child._isIntermediate) continue;
      if (entities.any(
          (entity) => sequence.matches(p.relative(entity.path, from: dir)))) {
        continue;
      }

      // We know this will fail, we're just doing it to force dart:io to emit
      // the exception it would if we were listing case-sensitively.
      await child
          .list(p.join(dir, (sequence.nodes.single as LiteralNode).text),
              fileSystem)
          .toList();
    }
  }

  /// Synchronously lists all entities within [dir] matching this node or its
  /// children.
  ///
  /// This may return duplicate entities. These will be filtered out in
  /// [ListTree.listSync].
  Iterable<FileSystemEntity> listSync(String dir, FileSystem fileSystem,
      {bool followLinks = true}) {
    if (isRecursive) {
      return fileSystem
          .directory(dir)
          .listSync(recursive: true, followLinks: followLinks)
          .where((entity) => _matches(p.relative(entity.path, from: dir)));
    }

    // Don't spawn extra [Directory.listSync] calls when we already know exactly
    // which subdirectories we're interested in.
    if (_isIntermediate && _caseSensitive) {
      return children!.entries.expand((entry) {
        var sequence = entry.key;
        var child = entry.value;
        return child.listSync(
            p.join(dir, (sequence.nodes.single as LiteralNode).text),
            fileSystem,
            followLinks: followLinks);
      });
    }

    var entities = fileSystem.directory(dir).listSync(followLinks: followLinks);
    _validateIntermediateChildrenSync(dir, entities, fileSystem);

    return entities.expand((entity) {
      var entities = <FileSystemEntity>[];
      var basename = p.relative(entity.path, from: dir);
      if (_matches(basename)) entities.add(entity);
      if (entity is! Directory) return entities;

      entities.addAll(children!.keys
          .where((sequence) => sequence.matches(basename))
          .expand((sequence) {
        try {
          return children![sequence]!
              .listSync(p.join(dir, basename), fileSystem,
                  followLinks: followLinks)
              .toList();
        } on FileSystemException catch (error) {
          // Ignore errors from directories not existing. We do this here so
          // that we only ignore warnings below wild cards. For example, the
          // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but
          // succeed if "foo/bar/qux/baz" doesn't exist.
          if (error.osError!.errorCode == _enoent ||
              error.osError!.errorCode == _enoentWin) {
            return const [];
          } else {
            rethrow;
          }
        }
      }));

      return entities;
    });
  }

  /// If this is a case-insensitive list, validates that all intermediate
  /// children (according to [_isIntermediate]) match at least one entity in
  /// [entities].
  ///
  /// This ensures that listing "foo/bar/*" fails on case-sensitive systems if
  /// "foo/bar" doesn't exist.
  void _validateIntermediateChildrenSync(
      String dir, List<FileSystemEntity> entities, FileSystem fileSystem) {
    if (_caseSensitive) return;

    children!.forEach((sequence, child) {
      if (!child._isIntermediate) return;
      if (entities.any(
          (entity) => sequence.matches(p.relative(entity.path, from: dir)))) {
        return;
      }

      // If there are no [entities] that match [sequence], manually list the
      // directory to force `dart:io` to throw an error. This allows us to
      // ensure that listing "foo/bar/*" fails on case-sensitive systems if
      // "foo/bar" doesn't exist.
      child.listSync(
          p.join(dir, (sequence.nodes.single as LiteralNode).text), fileSystem);
    });
  }

  /// Returns whether the native [path] matches [_validator].
  bool _matches(String path) =>
      _validator?.matches(toPosixPath(p.context, path)) ?? false;

  @override
  String toString() => '($_validator) $children';
}

/// Joins each [components] into a new glob where each component is separated by
/// a path separator.
SequenceNode _join(Iterable<AstNode> components) {
  var componentsList = components.toList();
  var first = componentsList.removeAt(0);
  var nodes = [first];
  for (var component in componentsList) {
    nodes.add(LiteralNode('/', caseSensitive: first.caseSensitive));
    nodes.add(component);
  }
  return SequenceNode(nodes, caseSensitive: first.caseSensitive);
}
