// Copyright (c) 2015, 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 pattern that matches against filesystem path-like strings with wildcards.
///
/// The pattern matches strings as follows:
///   * The pattern must use `/` as the path separator.
///   * The whole string must match, not a substring.
///   * Any non wildcard is matched as a literal.
///   * '*' matches one or more characters except '/'.
///   * '?' matches exactly one character except '/'.
///   * '**' matches one or more characters including '/'.
class Glob {
  /// The special characters are: \ ^ $ . | + [ ] ( ) { }
  /// as defined here: http://ecma-international.org/ecma-262/5.1/#sec-15.10
  static final RegExp _specialChars = RegExp(r'([\\\^\$\.\|\+\[\]\(\)\{\}])');

  /// The path separator used to separate components in file paths.
  final String _separator;

  /// The pattern string.
  final String _pattern;

  String _suffix;
  RegExp _regex;

  Glob(this._separator, this._pattern) {
    if (_hasJustPrefix(_pattern, '**/*')) {
      _suffix = _pattern.substring(4).toLowerCase();
    } else if (_hasJustPrefix(_pattern, '**')) {
      _suffix = _pattern.substring(2).toLowerCase();
    } else {
      _regex = _regexpFromGlobPattern(_pattern);
    }
  }

  @override
  int get hashCode => _pattern.hashCode;

  @override
  bool operator ==(other) => other is Glob && _pattern == other._pattern;

  /// Return `true` if the given [path] matches this glob.
  /// The given [path] must use the same [_separator] as the glob.
  bool matches(String path) {
    String posixPath = _toPosixPath(path);
    if (_suffix != null) {
      return posixPath.toLowerCase().endsWith(_suffix);
    }
    return _regex.matchAsPrefix(posixPath) != null;
  }

  @override
  String toString() => _pattern;

  /// Return the Posix version of the given [path].
  String _toPosixPath(String path) {
    if (_separator == '/') {
      return path;
    }
    return path.replaceAll(_separator, '/');
  }

  /// Return `true` if the [pattern] start with the given [prefix] and does
  /// not have `*` or `?` characters after the [prefix].
  static bool _hasJustPrefix(String pattern, String prefix) {
    if (pattern.startsWith(prefix)) {
      int prefixLength = prefix.length;
      return !pattern.contains('*', prefixLength) &&
          !pattern.contains('?', prefixLength);
    }
    return false;
  }

  static RegExp _regexpFromGlobPattern(String pattern) {
    StringBuffer sb = StringBuffer();
    sb.write('^');
    List<String> chars = pattern.split('');
    for (int i = 0; i < chars.length; i++) {
      String c = chars[i];
      if (_specialChars.hasMatch(c)) {
        sb.write(r'\');
        sb.write(c);
      } else if (c == '*') {
        if (i + 1 < chars.length && chars[i + 1] == '*') {
          sb.write('.*');
          i++;
        } else {
          sb.write('[^/]*');
        }
      } else if (c == '?') {
        sb.write('[^/]');
      } else {
        sb.write(c);
      }
    }
    sb.write(r'$');
    return RegExp(sb.toString(), caseSensitive: false);
  }
}
