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

import 'ast.dart';
import 'utils.dart';

const _HYPHEN = 0x2D;
const _SLASH = 0x2F;

/// A parser for globs.
class Parser {
  /// The scanner used to scan the source.
  final StringScanner _scanner;

  /// The path context for the glob.
  final p.Context _context;

  /// Whether this glob is case-sensitive.
  final bool _caseSensitive;

  Parser(String component, this._context, {bool caseSensitive: true})
      : _scanner = new StringScanner(component),
        _caseSensitive = caseSensitive;

  /// Parses an entire glob.
  SequenceNode parse() => _parseSequence();

  /// Parses a [SequenceNode].
  ///
  /// If [inOptions] is true, this is parsing within an [OptionsNode].
  SequenceNode _parseSequence({bool inOptions: false}) {
    var nodes = <AstNode>[];

    if (_scanner.isDone) {
      _scanner.error('expected a glob.', position: 0, length: 0);
    }

    while (!_scanner.isDone) {
      if (inOptions && (_scanner.matches(',') || _scanner.matches('}'))) break;
      nodes.add(_parseNode(inOptions: inOptions));
    }

    return new SequenceNode(nodes, caseSensitive: _caseSensitive);
  }

  /// Parses an [AstNode].
  ///
  /// If [inOptions] is true, this is parsing within an [OptionsNode].
  AstNode _parseNode({bool inOptions: false}) {
    var star = _parseStar();
    if (star != null) return star;

    var anyChar = _parseAnyChar();
    if (anyChar != null) return anyChar;

    var range = _parseRange();
    if (range != null) return range;

    var options = _parseOptions();
    if (options != null) return options;

    return _parseLiteral(inOptions: inOptions);
  }

  /// Tries to parse a [StarNode] or a [DoubleStarNode].
  ///
  /// Returns `null` if there's not one to parse.
  AstNode _parseStar() {
    if (!_scanner.scan('*')) return null;
    return _scanner.scan('*')
        ? new DoubleStarNode(_context, caseSensitive: _caseSensitive)
        : new StarNode(caseSensitive: _caseSensitive);
  }

  /// Tries to parse an [AnyCharNode].
  ///
  /// Returns `null` if there's not one to parse.
  AstNode _parseAnyChar() {
    if (!_scanner.scan('?')) return null;
    return new AnyCharNode(caseSensitive: _caseSensitive);
  }

  /// Tries to parse an [RangeNode].
  ///
  /// Returns `null` if there's not one to parse.
  AstNode _parseRange() {
    if (!_scanner.scan('[')) return null;
    if (_scanner.matches(']')) _scanner.error('unexpected "]".');
    var negated = _scanner.scan('!') || _scanner.scan('^');

    readRangeChar() {
      var char = _scanner.readChar();
      if (negated || char != _SLASH) return char;
      _scanner.error('"/" may not be used in a range.',
          position: _scanner.position - 1);
    }

    var ranges = <Range>[];
    while (!_scanner.scan(']')) {
      var start = _scanner.position;
      // Allow a backslash to escape a character.
      _scanner.scan('\\');
      var char = readRangeChar();

      if (_scanner.scan('-')) {
        if (_scanner.matches(']')) {
          ranges.add(new Range.singleton(char));
          ranges.add(new Range.singleton(_HYPHEN));
          continue;
        }

        // Allow a backslash to escape a character.
        _scanner.scan('\\');

        var end = readRangeChar();

        if (end < char) {
          _scanner.error("Range out of order.",
              position: start,
              length: _scanner.position - start);
        }
        ranges.add(new Range(char, end));
      } else {
        ranges.add(new Range.singleton(char));
      }
    }

    return new RangeNode(ranges,
        negated: negated, caseSensitive: _caseSensitive);
  }

  /// Tries to parse an [OptionsNode].
  ///
  /// Returns `null` if there's not one to parse.
  AstNode _parseOptions() {
    if (!_scanner.scan('{')) return null;
    if (_scanner.matches('}')) _scanner.error('unexpected "}".');

    var options = <SequenceNode>[];
    do {
      options.add(_parseSequence(inOptions: true));
    } while (_scanner.scan(','));

    // Don't allow single-option blocks.
    if (options.length == 1) _scanner.expect(',');
    _scanner.expect('}');

    return new OptionsNode(options, caseSensitive: _caseSensitive);
  }

  /// Parses a [LiteralNode].
  AstNode _parseLiteral({bool inOptions: false}) {
    // If we're in an options block, we want to stop parsing as soon as we hit a
    // comma. Otherwise, commas are fair game for literals.
    var regExp = new RegExp(
        inOptions ? r'[^*{[?\\}\],()]*' : r'[^*{[?\\}\]()]*');

    _scanner.scan(regExp);
    var buffer = new StringBuffer()..write(_scanner.lastMatch[0]);

    while (_scanner.scan('\\')) {
      buffer.writeCharCode(_scanner.readChar());
      _scanner.scan(regExp);
      buffer.write(_scanner.lastMatch[0]);
    }

    for (var char in const [']', '(', ')']) {
      if (_scanner.matches(char)) _scanner.error('unexpected "$char"');
    }
    if (!inOptions && _scanner.matches('}')) _scanner.error('unexpected "}"');

    return new LiteralNode(buffer.toString(),
        context: _context, caseSensitive: _caseSensitive);
  }
}
