// 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:path/path.dart' as p;

import 'src/ast.dart';
import 'src/io.dart';
import 'src/list_tree.dart';
import 'src/parser.dart';
import 'src/utils.dart';

/// Regular expression used to quote globs.
final _quoteRegExp = RegExp(r'[*{[?\\}\],\-()]');

/// A glob for matching and listing files and directories.
///
/// A glob matches an entire string as a path. Although the glob pattern uses
/// POSIX syntax, it can match against POSIX, Windows, or URL paths. The format
/// it expects paths to use is based on the `context` parameter to [new Glob];
/// it defaults to the current system's syntax.
///
/// Paths are normalized before being matched against a glob, so for example the
/// glob `foo/bar` matches the path `foo/./bar`. A relative glob can match an
/// absolute path and vice versa; globs and paths are both interpreted as
/// relative to `context.current`, which defaults to the current working
/// directory.
///
/// When used as a [Pattern], a glob will return either one or zero matches for
/// a string depending on whether the entire string matches the glob. These
/// matches don't currently have capture groups, although this may change in the
/// future.
class Glob implements Pattern {
  /// The pattern used to create this glob.
  final String pattern;

  /// The context in which paths matched against this glob are interpreted.
  final p.Context context;

  /// If true, a path matches if it matches the glob itself or is recursively
  /// contained within a directory that matches.
  final bool recursive;

  /// Whether the glob matches paths case-sensitively.
  bool get caseSensitive => _ast.caseSensitive;

  /// The parsed AST of the glob.
  final AstNode _ast;

  ListTree _listTree;

  /// Whether [context]'s current directory is absolute.
  bool get _contextIsAbsolute {
    if (_contextIsAbsoluteCache == null) {
      _contextIsAbsoluteCache = context.isAbsolute(context.current);
    }
    return _contextIsAbsoluteCache;
  }

  bool _contextIsAbsoluteCache;

  /// Whether [pattern] could match absolute paths.
  bool get _patternCanMatchAbsolute {
    if (_patternCanMatchAbsoluteCache == null) {
      _patternCanMatchAbsoluteCache = _ast.canMatchAbsolute;
    }
    return _patternCanMatchAbsoluteCache;
  }

  bool _patternCanMatchAbsoluteCache;

  /// Whether [pattern] could match relative paths.
  bool get _patternCanMatchRelative {
    if (_patternCanMatchRelativeCache == null) {
      _patternCanMatchRelativeCache = _ast.canMatchRelative;
    }
    return _patternCanMatchRelativeCache;
  }

  bool _patternCanMatchRelativeCache;

  /// Returns [contents] with characters that are meaningful in globs
  /// backslash-escaped.
  static String quote(String contents) =>
      contents.replaceAllMapped(_quoteRegExp, (match) => '\\${match[0]}');

  /// Creates a new glob with [pattern].
  ///
  /// Paths matched against the glob are interpreted according to [context]. It
  /// defaults to the system context.
  ///
  /// If [recursive] is true, this glob matches and lists not only the files and
  /// directories it explicitly matches, but anything beneath those as well.
  ///
  /// If [caseSensitive] is true, this glob matches and lists only files whose
  /// case matches that of the characters in the glob. Otherwise, it matches
  /// regardless of case. This defaults to `false` when [context] is Windows and
  /// `true` otherwise.
  factory Glob(String pattern,
      {p.Context context, bool recursive = false, bool caseSensitive}) {
    context ??= p.context;
    caseSensitive ??= context.style == p.Style.windows ? false : true;
    if (recursive) pattern += "{,/**}";

    var parser = Parser(pattern, context, caseSensitive: caseSensitive);
    return Glob._(pattern, context, parser.parse(), recursive);
  }

  Glob._(this.pattern, this.context, this._ast, this.recursive);

  /// Lists all [FileSystemEntity]s beneath [root] that match the glob.
  ///
  /// This works much like [Directory.list], but it only lists directories that
  /// could contain entities that match the glob. It provides no guarantees
  /// about the order of the returned entities, although it does guarantee that
  /// only one entity with a given path will be returned.
  ///
  /// [root] defaults to the current working directory.
  ///
  /// [followLinks] works the same as for [Directory.list].
  Stream<FileSystemEntity> list({String root, bool followLinks = true}) {
    if (context.style != p.style) {
      throw StateError("Can't list glob \"$this\"; it matches "
          "${context.style} paths, but this platform uses ${p.style} paths.");
    }

    if (_listTree == null) _listTree = ListTree(_ast);
    return _listTree.list(root: root, followLinks: followLinks);
  }

  /// Synchronously lists all [FileSystemEntity]s beneath [root] that match the
  /// glob.
  ///
  /// This works much like [Directory.listSync], but it only lists directories
  /// that could contain entities that match the glob. It provides no guarantees
  /// about the order of the returned entities, although it does guarantee that
  /// only one entity with a given path will be returned.
  ///
  /// [root] defaults to the current working directory.
  ///
  /// [followLinks] works the same as for [Directory.list].
  List<FileSystemEntity> listSync({String root, bool followLinks = true}) {
    if (context.style != p.style) {
      throw StateError("Can't list glob \"$this\"; it matches "
          "${context.style} paths, but this platform uses ${p.style} paths.");
    }

    if (_listTree == null) _listTree = ListTree(_ast);
    return _listTree.listSync(root: root, followLinks: followLinks);
  }

  /// Returns whether this glob matches [path].
  bool matches(String path) => matchAsPrefix(path) != null;

  Match matchAsPrefix(String path, [int start = 0]) {
    // Globs are like anchored RegExps in that they only match entire paths, so
    // if the match starts anywhere after the first character it can't succeed.
    if (start != 0) return null;

    if (_patternCanMatchAbsolute &&
        (_contextIsAbsolute || context.isAbsolute(path))) {
      var absolutePath = context.normalize(context.absolute(path));
      if (_ast.matches(toPosixPath(context, absolutePath))) {
        return GlobMatch(path, this);
      }
    }

    if (_patternCanMatchRelative) {
      var relativePath = context.relative(path);
      if (_ast.matches(toPosixPath(context, relativePath))) {
        return GlobMatch(path, this);
      }
    }

    return null;
  }

  Iterable<Match> allMatches(String path, [int start = 0]) {
    var match = matchAsPrefix(path, start);
    return match == null ? [] : [match];
  }

  String toString() => pattern;
}
