// Copyright (c) 2016, 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:source_span/source_span.dart';

import 'ast.dart';
import 'scanner.dart';
import 'token.dart';

/// A class for parsing a boolean selector.
///
/// Boolean selectors use a stripped-down version of the Dart expression syntax
/// that only contains variables, parentheses, and boolean operators. Variables
/// may also contain dashes, contrary to Dart's syntax; this allows consistency
/// with command-line arguments.
class Parser {
  /// The scanner that tokenizes the selector.
  final Scanner _scanner;

  Parser(String selector) : _scanner = Scanner(selector);

  /// Parses the selector.
  ///
  /// This must only be called once per parser.
  Node parse() {
    var selector = _conditional();

    if (_scanner.peek().type != TokenType.endOfFile) {
      throw SourceSpanFormatException(
          'Expected end of input.', _scanner.peek().span);
    }

    return selector;
  }

  /// Parses a conditional:
  ///
  ///     conditionalExpression:
  ///       logicalOrExpression ("?" conditionalExpression ":"
  ///           conditionalExpression)?
  Node _conditional() {
    var condition = _or();
    if (!_scanner.scan(TokenType.questionMark)) return condition;

    var whenTrue = _conditional();
    if (!_scanner.scan(TokenType.colon)) {
      throw SourceSpanFormatException('Expected ":".', _scanner.peek().span);
    }

    var whenFalse = _conditional();
    return ConditionalNode(condition, whenTrue, whenFalse);
  }

  /// Parses a logical or:
  ///
  ///     logicalOrExpression:
  ///       logicalAndExpression ("||" logicalOrExpression)?
  Node _or() {
    var left = _and();
    if (!_scanner.scan(TokenType.or)) return left;
    return OrNode(left, _or());
  }

  /// Parses a logical and:
  ///
  ///     logicalAndExpression:
  ///       simpleExpression ("&&" logicalAndExpression)?
  Node _and() {
    var left = _simpleExpression();
    if (!_scanner.scan(TokenType.and)) return left;
    return AndNode(left, _and());
  }

  /// Parses a simple expression:
  ///
  ///     simpleExpression:
  ///       "!" simpleExpression |
  ///           "(" conditionalExpression ")" |
  ///           IDENTIFIER
  Node _simpleExpression() {
    var token = _scanner.next();
    switch (token.type) {
      case TokenType.not:
        var child = _simpleExpression();
        return NotNode(child, token.span.expand(child.span));

      case TokenType.leftParen:
        var child = _conditional();
        if (!_scanner.scan(TokenType.rightParen)) {
          throw SourceSpanFormatException(
              'Expected ")".', _scanner.peek().span);
        }
        return child;

      case TokenType.identifier:
        return VariableNode((token as IdentifierToken).name, token.span);

      default:
        throw SourceSpanFormatException('Expected expression.', token.span);
    }
  }
}
