// 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 ==(Object 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);
  }
}
