// Copyright (c) 2020, 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.

/// Implements an [Ignore] filter compatible with `.gitignore`.
///
/// An [Ignore] instance holds a set of [`.gitignore` rules][1], and allows
/// testing if a given path is ignored.
///
/// **Example**:
/// ```dart
/// import 'package:ignore/ignore.dart';
///
/// void main() {
///   final ignore = Ignore([
///     '*.o',
///   ]);
///
///   print(ignore.ignores('main.o')); // true
///   print(ignore.ignores('main.c')); // false
/// }
/// ```
///
/// For a generic walk of a file-hierarchy with ignore files at all levels see
/// [Ignore.listFiles].
///
/// [1]: https://git-scm.com/docs/gitignore

import 'package:meta/meta.dart';

/// A set of ignore rules representing a single ignore file.
///
/// An [Ignore] instance holds [`.gitignore` rules][1] relative to a given path.
///
/// **Example**:
/// ```dart
/// import 'package:ignore/ignore.dart';
///
/// void main() {
///   final ignore = Ignore([
///     '*.o',
///   ]);
///
///   print(ignore.ignores('main.o')); // true
///   print(ignore.ignores('main.c')); // false
/// }
/// ```
///
/// [1]: https://git-scm.com/docs/gitignore
@sealed
class Ignore {
  final List<_IgnoreRule> _rules;

  /// Create an [Ignore] instance with a set of [`.gitignore` compatible][1]
  /// patterns.
  ///
  /// Each value in [patterns] will be interpreted as one or more lines from
  /// a `.gitignore` file, in compliance with the [`.gitignore` manual page][1].
  ///
  /// The keys of 'pattern' are the directories to intpret the rules relative
  /// to. The root should be the empty string, and sub-directories are separated
  /// by '/' (but no final '/').
  ///
  /// If [ignoreCase] is `true`, patterns will be case-insensitive. By default
  /// `git` is case-sensitive. But case insensitivity can be enabled when a
  /// repository is created, or by configuration option, see
  /// [`core.ignoreCase` documentation][2] for details.
  ///
  /// If [onInvalidPattern] is passed, it will be called with a
  /// [FormatException] describing the problem. The exception will have [source]
  /// as source.
  ///
  /// **Example**:
  /// ```dart
  /// import 'package:ignore/ignore.dart';
  /// void main() {
  ///   final ignore = Ignore({'': [
  ///     // You can pass an entire .gitignore file as a single string.
  ///     // You can also pass it as a list of lines, or both.
  ///     '''
  /// # Comment in a .gitignore file
  /// obj/
  /// *.o
  /// !main.o
  ///   '''
  ///   }]);
  ///
  ///   print(ignore.ignores('obj/README.md')); // true
  ///   print(ignore.ignores('lib.o')); // false
  ///   print(ignore.ignores('main.o')); // false
  /// }
  /// ```
  ///
  /// [1]: https://git-scm.com/docs/gitignore
  /// [2]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreignoreCase
  Ignore(
    Iterable<String> patterns, {
    bool ignoreCase = false,
    void Function(String pattern, FormatException exception) onInvalidPattern,
  }) : _rules = _parseIgnorePatterns(patterns, ignoreCase,
            onInvalidPattern: onInvalidPattern);

  /// Returns `true` if [path] is ignored by the patterns used to create this
  /// [Ignore] instance, assuming those patterns are placed at `.`.
  ///
  /// The [path] must be a relative path, not starting with `./`, `../`, and
  /// must end in slash (`/`) if it is directory.
  ///
  /// **Example**:
  /// ```dart
  /// import 'package:ignore/ignore.dart';
  ///
  /// void main() {
  ///   final ignore = Ignore([
  ///     '*.o',
  ///   ]);
  ///
  ///   print(ignore.ignores('main.o')); // true
  ///   print(ignore.ignores('main.c')); // false
  ///   print(ignore.ignores('lib/')); // false
  ///   print(ignore.ignores('lib/helper.o')); // true
  ///   print(ignore.ignores('lib/helper.c')); // false
  /// }
  /// ```
  bool ignores(String path) {
    ArgumentError.checkNotNull(path, 'path');
    if (path.isEmpty) {
      throw ArgumentError.value(path, 'path', 'must be not empty');
    }
    if (path.startsWith('/') ||
        path.startsWith('./') ||
        path.startsWith('../') ||
        path == '.' ||
        path == '..') {
      throw ArgumentError.value(
        path,
        'path',
        'must be relative, and not start with "./", "../"',
      );
    }
    if (_rules.isEmpty) {
      return false;
    }
    final pathWithoutSlash =
        path.endsWith('/') ? path.substring(0, path.length - 1) : path;
    return listFiles(
      beneath: pathWithoutSlash,
      includeDirs: true,
      listDir: (dir) {
        // List the next part of path:
        if (dir == pathWithoutSlash) return [];
        final startOfNext = dir.isEmpty ? 0 : dir.length + 1;
        final nextSlash = path.indexOf('/', startOfNext);
        return [path.substring(startOfNext, nextSlash)];
      },
      ignoreForDir: (dir) => dir == '' ? this : null,
      isDir: (candidate) =>
          path.length > candidate.length && path[candidate.length] == '/',
    ).isEmpty;
  }

  /// Returns all the files in the tree under (and including) [beneath] not
  /// ignored by ignore-files from [root] and down.
  ///
  /// Represents paths normalized  using '/' as directory separator. The empty
  /// relative path is '.', no '..' are allowed.
  ///
  /// [beneath] must start with [root] and even if it is a directory it should not
  /// end with '/', if [beneath] is not provided, everything under root is
  /// included.
  ///
  /// [listDir] should enumerate the immediate contents of a given directory,
  /// returning paths including [root].
  ///
  /// [isDir] should return true if the argument is a directory. It will only be
  /// queried with file-names under (and including) [beneath]
  ///
  /// [ignoreForDir] should retrieve the ignore rules for a single directory
  /// or return `null` if there is no ignore rules.
  ///
  /// If [includeDirs] is true non-ignored directories will be included in the
  /// result (including beneath).
  ///
  /// This example program lists all files under second argument that are
  /// not ignored by .gitignore files from first argument and below:
  ///
  /// ```dart
  /// import 'dart:io';
  /// import 'package:path/path.dart' as p;
  /// import 'package:pub/src/ignore.dart';
  ///
  /// void main(List<String> args) {
  ///   var root = p.normalize(args[0]);
  ///   if (root == '.') root = '';
  ///   var beneath = args.length > 1 ? p.normalize(args[1]) : root;
  ///   if (beneath == '.') beneath = '';
  ///   String resolve(String path) {
  ///     return p.joinAll([root, ...p.posix.split(path)]);
  ///   }
  ///
  ///   Ignore.listFiles(
  ///     beneath: beneath,
  ///     listDir: (dir) => Directory(resolve(dir)).listSync().map((x) {
  ///        final relative = p.relative(x.path, from: root);
  ///       return p.posix.joinAll(p.split(relative));
  ///     }),
  ///     ignoreForDir: (dir) {
  ///       final f = File(resolve('dir/.gitignore'));
  ///       return f.existsSync() ? Ignore([f.readAsStringSync()]) : null;
  ///     },
  ///     isDir: (dir) => Directory(resolve(dir)).existsSync(),
  ///   ).forEach(print);
  /// }
  /// ```
  static List<String> listFiles({
    String beneath = '',
    @required Iterable<String> Function(String) listDir,
    @required Ignore Function(String) ignoreForDir,
    @required bool Function(String) isDir,
    bool includeDirs = false,
  }) {
    if (beneath.startsWith('/') ||
        beneath.startsWith('./') ||
        beneath.startsWith('../')) {
      throw ArgumentError.value(
          'must be relative and normalized', 'beneath', beneath);
    }
    if (beneath.endsWith('/')) {
      throw ArgumentError.value('must not end with /', beneath);
    }
    // To streamline the algorithm we represent all paths as starting with '/'
    // and the empty path as just '/'.
    if (beneath == '.') beneath = '';
    beneath = '/$beneath';

    // Will contain all the files that are not ignored.
    final result = <String>[];
    // At any given point in the search, this will contain the Ignores from
    // directories leading up to the current entity.
    // The single `null` aligns popping and pushing in this stack with [toVisit]
    // below.
    final ignoreStack = <_IgnorePrefixPair>[null];
    // Find all ignores between './' and [beneath] (not inclusive).

    // [index] points at the next '/' in the path.
    var index = -1;
    while ((index = beneath.indexOf('/', index + 1)) != -1) {
      final partial = beneath.substring(0, index + 1);
      if (_matchesStack(ignoreStack, partial)) {
        // A directory on the way towards [beneath] was ignored. Empty result.
        return <String>[];
      }
      final ignore = ignoreForDir(
          partial == '/' ? '.' : partial.substring(1, partial.length - 1));
      ignoreStack
          .add(ignore == null ? null : _IgnorePrefixPair(ignore, partial));
    }
    // Do a depth first tree-search starting at [beneath].
    // toVisit is a stack containing all items that are waiting to be processed.
    final toVisit = [
      [beneath]
    ];
    while (toVisit.isNotEmpty) {
      final topOfStack = toVisit.last;
      if (topOfStack.isEmpty) {
        toVisit.removeLast();
        ignoreStack.removeLast();
        continue;
      }
      final current = topOfStack.removeLast();
      // This is the version of current we present to the callbacks and in
      // [result].
      //
      // The empty path is represented as '.' and there is no leading '/'.
      final normalizedCurrent = current == '/' ? '.' : current.substring(1);
      final currentIsDir = isDir(normalizedCurrent);
      if (_matchesStack(ignoreStack, currentIsDir ? '$current/' : current)) {
        // current was ignored. Continue with the next item.
        continue;
      }
      if (currentIsDir) {
        final ignore = ignoreForDir(normalizedCurrent);
        ignoreStack
            .add(ignore == null ? null : _IgnorePrefixPair(ignore, current));
        // Put all entities in current on the stack to be processed.
        toVisit.add(listDir(normalizedCurrent).map((x) => '/$x').toList());
        if (includeDirs) {
          result.add(normalizedCurrent);
        }
      } else {
        result.add(normalizedCurrent);
      }
    }
    return result;
  }
}

class _IgnoreParseResult {
  // The parsed pattern.
  final String pattern;

  // The resulting matching rule. `null` if the pattern was empty or invalid.
  final _IgnoreRule rule;

  // An invalid pattern is also considered empty.
  bool get empty => rule == null;
  bool get valid => exception == null;

  // For invalid patterns this contains a description of the problem.
  final FormatException exception;

  _IgnoreParseResult(this.pattern, this.rule) : exception = null;
  _IgnoreParseResult.invalid(this.pattern, this.exception) : rule = null;
  _IgnoreParseResult.empty(this.pattern)
      : rule = null,
        exception = null;
}

class _IgnoreRule {
  /// A regular expression that represents this rule.
  final RegExp pattern;
  final bool negative;

  /// The String this pattern was generated from.
  final String original;

  _IgnoreRule(this.pattern, this.negative, this.original);

  @override
  String toString() {
    // TODO: implement toString
    return '$original -> $pattern';
  }
}

/// [onInvalidPattern] can be used to handle parse failures. If
/// [onInvalidPattern] is `null` invalid patterns are ignored.
List<_IgnoreRule> _parseIgnorePatterns(
  Iterable<String> patterns,
  bool ignoreCase, {
  void Function(String pattern, FormatException exception) onInvalidPattern,
}) {
  ArgumentError.checkNotNull(patterns, 'patterns');
  ArgumentError.checkNotNull(ignoreCase, 'ignoreCase');

  final parsedPatterns = patterns
      .map((s) => s.split('\n'))
      .expand((e) => e)
      .map((pattern) => _parseIgnorePattern(pattern, ignoreCase));
  if (onInvalidPattern != null) {
    for (final invalidResult
        in parsedPatterns.where((result) => !result.valid)) {
      onInvalidPattern(invalidResult.pattern, invalidResult.exception);
    }
  }
  return parsedPatterns.where((r) => !r.empty).map((r) => r.rule).toList();
}

_IgnoreParseResult _parseIgnorePattern(String pattern, bool ignoreCase) {
  // Check if patterns is a comment
  if (pattern.startsWith('#')) {
    return _IgnoreParseResult.empty(pattern);
  }
  var first = 0;
  var end = pattern.length;

  // Detect negative patterns
  final negative = pattern.startsWith('!');
  if (negative) {
    first++;
  }

  // Remove trailing whitespace unless escaped
  while (end != 0 &&
      pattern[end - 1] == ' ' &&
      (end == 1 || pattern[end - 2] != '\\')) {
    end--;
  }
  // Empty patterns match nothing.
  if (first == end) return _IgnoreParseResult.empty(pattern);

  var current = first;
  String peekChar() => current >= end ? null : pattern[current];

  var expr = '';

  // Parses the inside of a [] range. Returns the value as a RegExp character
  // range, or null if the pattern was broken.
  String parseCharacterRange() {
    var characterRange = '';
    var first = true;
    for (;;) {
      final nextChar = peekChar();
      if (nextChar == null) {
        return null;
      }
      current++;
      if (nextChar == '\\') {
        final escaped = peekChar();
        if (escaped == null) {
          return null;
        }
        current++;

        characterRange += escaped == '-' ? r'\-' : RegExp.escape(escaped);
      } else if (nextChar == '!' && first) {
        characterRange += '^';
      } else if (nextChar == ']' && first) {
        characterRange += RegExp.escape(nextChar);
      } else if (nextChar == ']') {
        assert(!first);
        return characterRange;
      } else {
        characterRange += nextChar;
      }
      first = false;
    }
  }

  var relativeToPath = false;
  var matchesDirectoriesOnly = false;

  // slashes have different significance depending on where they are in
  // the String. Handle that here.
  void handleSlash() {
    if (current == end) {
      // A slash at the end makes us only match directories.
      matchesDirectoriesOnly = true;
    } else {
      // A slash anywhere else makes the pattern relative anchored at the
      // current path.
      relativeToPath = true;
    }
  }

  for (;;) {
    final nextChar = peekChar();
    if (nextChar == null) break;
    current++;
    if (nextChar == '*') {
      if (peekChar() == '*') {
        // Handle '**'
        current++;
        if (peekChar() == '/') {
          current++;
          if (current == end) {
            expr += '.*';
          } else {
            // Match nothing or a path followed by '/'
            expr += '(?:(?:)|(?:.*/))';
          }
          // Handle the side effects of seeing a slash.
          handleSlash();
        } else {
          expr += '.*';
        }
      } else {
        // Handle a single '*'
        expr += '[^/]*';
      }
    } else if (nextChar == '?') {
      // Handle '?'
      expr += '[^/]';
    } else if (nextChar == '[') {
      // Character ranges
      final characterRange = parseCharacterRange();
      if (characterRange == null) {
        return _IgnoreParseResult.invalid(
          pattern,
          FormatException(
              'Pattern "$pattern" had an invalid `[a-b]` style character range',
              pattern,
              current),
        );
      }
      expr += '[$characterRange]';
    } else if (nextChar == '\\') {
      // Escapes
      final escaped = peekChar();
      if (escaped == null) {
        return _IgnoreParseResult.invalid(
          pattern,
          FormatException(
              'Pattern "$pattern" end of pattern inside character escape.',
              pattern,
              current),
        );
      }
      expr += RegExp.escape(escaped);
      current++;
    } else {
      if (nextChar == '/') {
        if (current - 1 != first && current != end) {
          // If slash appears in the beginning we don't want it manifest in the
          // regexp.
          expr += '/';
        }
        handleSlash();
      } else {
        expr += RegExp.escape(nextChar);
      }
    }
  }
  if (relativeToPath) {
    expr = '^$expr';
  } else {
    expr = '(?:^|/)$expr';
  }
  if (matchesDirectoriesOnly) {
    expr = '$expr/\$';
  } else {
    expr = '$expr/?\$';
    // expr = '$expr\$';
  }
  try {
    return _IgnoreParseResult(
        pattern,
        _IgnoreRule(
            RegExp(expr, caseSensitive: !ignoreCase), negative, pattern));
  } on FormatException catch (e) {
    throw AssertionError(
        'Created broken expression "$expr" from ignore pattern "$pattern" -> $e');
  }
}

/// A [Ignore] object, paired with the prefix where it is found in the directory
/// hierarchy.
class _IgnorePrefixPair {
  final Ignore ignore;
  final String prefix;
  _IgnorePrefixPair(this.ignore, this.prefix);
  @override
  String toString() {
    return '{${ignore._rules.map((r) => r.original)} $prefix}';
  }
}

/// Returns true if any of [ignores] has a match of [path] that is not negated
/// by a later one.
///
/// expects [path] to start with '/'
///
/// If [path] should be matched as a directory, it should end with '/'.
bool _matchesStack(List<_IgnorePrefixPair> ignores, String path) {
  // This is optimized by trying the rules in reverse order.
  // If a rule matches, the result is true if the rule is not negative.
  for (final ignorePair in ignores.reversed) {
    if (ignorePair == null) continue;
    final prefixLength = ignorePair.prefix.length;
    final s =
        prefixLength == 0 ? path : path.substring(ignorePair.prefix.length);
    for (final rule in ignorePair.ignore._rules.reversed) {
      if (rule.pattern.hasMatch(s)) {
        return !rule.negative;
      }
    }
  }
  return false;
}
