// 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
library;

/// 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
final 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 interpret 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 the
  /// pattern 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(
    List<String> patterns, {
    bool ignoreCase = false,
    void Function(String pattern, FormatException exception)? onInvalidPattern,
  }) : _rules = _parseIgnorePatterns(
         patterns,
         ignoreCase,
         onInvalidPattern: onInvalidPattern,
       ).toList(growable: false);

  /// 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,
      // because we are listing below pathWithoutSlash
      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 == '.' || dir.isEmpty ? this : null,
      isDir:
          (candidate) =>
              candidate == '.' ||
              candidate.isEmpty ||
              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 the "root" path '.' and down.
  ///
  /// Represents paths normalized  using '/' as directory separator. The empty
  /// relative path is '.', no '..' are allowed.
  ///
  /// [beneath] must be relative to the root and even if it is a directory it
  /// should not end with '/', if [beneath] is not provided, everything under
  /// the root '.' is included.
  ///
  /// [listDir] should enumerate the immediate contents of a given directory,
  /// returning paths including the root '.'. This function can be used to list
  /// directories relative to any 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 == '/' ? current : '$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';
  }
}

/// Pattern for a line-break which accepts CR LF and LF.
final _lineBreakPattern = RegExp('\r?\n');

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

  final parsedPatterns = patterns
      .expand((s) => s.split(_lineBreakPattern))
      .map((pattern) => _parseIgnorePattern(pattern, ignoreCase));

  for (final r in parsedPatterns) {
    if (!r.valid) {
      onInvalidPattern(r.pattern, r.exception!);
    }
    if (!r.empty) {
      yield r.rule!;
    }
  }
}

_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];
  String? previous() => current < 2 ? null : pattern[current - 2];

  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 if ((previous() == '/') && peekChar() == null) {
        // /a/* should not match '/a/', so we require at least one character
        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/?\$';
  }
  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;
}
