/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.idea.blaze.base.lang.buildfile.parser;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.lang.buildfile.lexer.TokenKind;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildElementType;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildElementTypes;
import com.intellij.lang.PsiBuilder;
import com.intellij.openapi.diagnostic.Logger;
import java.util.EnumSet;
import java.util.List;

/** For parsing expressions in BUILD files. */
public class ExpressionParsing extends Parsing {

  private static final Logger LOG =
      Logger.getInstance("com.google.idea.blaze.base.lang.buildfile.parser.ExpressionParsing");

  private static final ImmutableSet<TokenKind> LIST_TERMINATOR_SET =
      ImmutableSet.of(TokenKind.EOF, TokenKind.RBRACKET, TokenKind.SEMI);

  private static final ImmutableSet<TokenKind> DICT_TERMINATOR_SET =
      ImmutableSet.of(TokenKind.EOF, TokenKind.RBRACE, TokenKind.SEMI);

  private static final ImmutableSet<TokenKind> EXPR_LIST_TERMINATOR_SET =
      ImmutableSet.of(
          TokenKind.EOF,
          TokenKind.NEWLINE,
          TokenKind.EQUALS,
          TokenKind.RBRACE,
          TokenKind.RBRACKET,
          TokenKind.RPAREN,
          TokenKind.SEMI);

  private static final ImmutableSet<TokenKind> EXPR_TERMINATOR_SET =
      ImmutableSet.of(
          TokenKind.EOF,
          TokenKind.COLON,
          TokenKind.COMMA,
          TokenKind.FOR,
          TokenKind.MINUS,
          TokenKind.PERCENT,
          TokenKind.PLUS,
          TokenKind.RBRACKET,
          TokenKind.RPAREN,
          TokenKind.SLASH);

  private static final ImmutableSet<TokenKind> BINARY_OPERATORS =
      ImmutableSet.of(
          TokenKind.AND,
          TokenKind.EQUALS_EQUALS,
          TokenKind.GREATER,
          TokenKind.GREATER_EQUALS,
          TokenKind.IN,
          TokenKind.LESS,
          TokenKind.LESS_EQUALS,
          TokenKind.MINUS,
          TokenKind.NOT_EQUALS,
          TokenKind.NOT_IN,
          TokenKind.OR,
          TokenKind.PERCENT,
          TokenKind.SLASH,
          TokenKind.PLUS,
          TokenKind.PIPE,
          TokenKind.STAR);

  private static final ImmutableSet<TokenKind> FUNCALL_TERMINATOR_SET =
      ImmutableSet.of(TokenKind.EOF, TokenKind.RPAREN, TokenKind.SEMI, TokenKind.NEWLINE);

  /**
   * Highest precedence goes last. Based on:
   * http://docs.python.org/2/reference/expressions.html#operator-precedence
   */
  private static final List<EnumSet<TokenKind>> OPERATOR_PRECEDENCE =
      ImmutableList.of(
          EnumSet.of(TokenKind.OR),
          EnumSet.of(TokenKind.AND),
          EnumSet.of(TokenKind.NOT),
          EnumSet.of(
              TokenKind.EQUALS_EQUALS,
              TokenKind.NOT_EQUALS,
              TokenKind.LESS,
              TokenKind.LESS_EQUALS,
              TokenKind.GREATER,
              TokenKind.GREATER_EQUALS,
              TokenKind.IN,
              TokenKind.NOT_IN),
          EnumSet.of(TokenKind.PIPE),
          EnumSet.of(TokenKind.MINUS, TokenKind.PLUS),
          EnumSet.of(TokenKind.SLASH, TokenKind.STAR, TokenKind.PERCENT));

  public ExpressionParsing(ParsingContext context) {
    super(context);
  }

  public void parseExpression(boolean insideParens) {
    // handle lists without parens (e.g. 'a,b,c = 1')
    PsiBuilder.Marker marker = insideParens ? null : builder.mark();
    parseNonTupleExpression();
    if (currentToken() == TokenKind.COMMA) {
      parseExpressionList();
      if (marker != null) {
        marker.done(BuildElementTypes.LIST_LITERAL);
      }
    } else if (marker != null) {
      marker.drop();
    }
  }

  // expr_list ::= ( ',' expr )* ','?
  private void parseExpressionList() {
    while (matches(TokenKind.COMMA)) {
      if (atAnyOfTokens(EXPR_LIST_TERMINATOR_SET)) {
        break;
      }
      parseNonTupleExpression();
    }
  }

  protected void parseNonTupleExpression() {
    parseNonTupleExpression(0);
    // don't bother including conditional expressions for now,
    //just include their components serially
    if (matches(TokenKind.IF)) {
      parseNonTupleExpression(0);
      if (matches(TokenKind.ELSE)) {
        parseNonTupleExpression();
      }
    }
  }

  private void parseNonTupleExpression(int prec) {
    if (prec >= OPERATOR_PRECEDENCE.size()) {
      parsePrimaryWithSuffix();
      return;
    }
    if (currentToken() == TokenKind.NOT && OPERATOR_PRECEDENCE.get(prec).contains(TokenKind.NOT)) {
      // special case handling of multi-token 'NOT IN' binary operator
      if (kindFromElement(builder.lookAhead(1)) != TokenKind.IN) {
        // skip the 'not' -- no need for a specific 'not' expression
        builder.advanceLexer();
        parseNonTupleExpression(prec + 1);
        return;
      }
    }
    parseBinOpExpression(prec);
  }

  /**
   * binop_expression ::= binop_expression OP binop_expression | parsePrimaryWithSuffix This
   * function takes care of precedence between operators (see OPERATOR_PRECEDENCE for the order),
   * and it assumes left-to-right associativity.
   */
  private void parseBinOpExpression(int prec) {
    PsiBuilder.Marker marker = builder.mark();
    parseNonTupleExpression(prec + 1);

    while (true) {
      if (!atBinaryOperator(prec)) {
        marker.drop();
        return;
      }
      parseNonTupleExpression(prec + 1);
      marker.done(BuildElementTypes.BINARY_OP_EXPRESSION);
      marker = marker.precede();
    }
  }

  /**
   * Consumes current token iff it's a binary operator at the given precedence level (with
   * special-case handling of 'NOT' 'IN' double token binary operator)
   */
  private boolean atBinaryOperator(int prec) {
    if (matchesAnyOf(OPERATOR_PRECEDENCE.get(prec))) {
      return true;
    }
    if (matchesSequence(TokenKind.NOT, TokenKind.IN)) {
      return true;
    }
    return false;
  }

  // primary_with_suffix ::= primary (selector_suffix | substring_suffix)*
  private void parsePrimaryWithSuffix() {
    PsiBuilder.Marker marker = builder.mark();
    parsePrimary();
    while (true) {
      if (matches(TokenKind.DOT)) {
        marker = parseSelectorSuffix(marker);
      } else if (matches(TokenKind.LBRACKET)) {
        marker = parseSubstringSuffix(marker);
      } else {
        break;
      }
    }
    marker.drop();
  }

  // selector_suffix ::= '.' IDENTIFIER [funcall_suffix]
  private PsiBuilder.Marker parseSelectorSuffix(PsiBuilder.Marker marker) {
    if (!atToken(TokenKind.IDENTIFIER)) {
      builder.error("expected identifier after dot");
      syncPast(EXPR_TERMINATOR_SET);
      return marker;
    }
    parseTargetOrReferenceIdentifier();
    if (atToken(TokenKind.LPAREN)) {
      parseFuncallSuffix();
      marker.done(BuildElementTypes.FUNCALL_EXPRESSION);
    } else {
      marker.done(BuildElementTypes.DOT_EXPRESSION);
    }
    return marker.precede();
  }

  // substring_suffix ::= '[' expression? ':' expression? ':' expression? ']'
  private PsiBuilder.Marker parseSubstringSuffix(PsiBuilder.Marker marker) {
    if (!atToken(TokenKind.COLON)) {
      PsiBuilder.Marker pos = builder.mark();
      parseExpression(false);
      pos.done(BuildElementTypes.POSITIONAL);
    }
    while (!matches(TokenKind.RBRACKET)) {
      if (expect(TokenKind.COLON)) {
        if (!atAnyOfTokens(TokenKind.COLON, TokenKind.RBRACKET)) {
          parseNonTupleExpression();
        }
      } else {
        syncPast(EXPR_LIST_TERMINATOR_SET);
        break;
      }
    }
    marker.done(BuildElementTypes.FUNCALL_EXPRESSION);
    return marker.precede();
  }

  private void parseTargetOrReferenceIdentifier() {
    if (!atToken(TokenKind.IDENTIFIER)) {
      builder.error("expected an identifier");
      return;
    }
    // TODO: handle assigning to a list of targets (e.g. "a,b = 1")
    TokenKind next = kindFromElement(builder.lookAhead(1));
    if (next == TokenKind.EQUALS || next == TokenKind.IN) {
      buildTokenElement(BuildElementTypes.TARGET_EXPRESSION);
    } else {
      buildTokenElement(BuildElementTypes.REFERENCE_EXPRESSION);
    }
  }

  private void parsePrimary() {
    TokenKind current = currentToken();
    switch (current) {
      case INT:
        buildTokenElement(BuildElementTypes.INTEGER_LITERAL);
        return;
      case STRING:
        parseStringLiteral(true);
        return;
      case IDENTIFIER:
        PsiBuilder.Marker marker = builder.mark();
        String tokenText = builder.getTokenText();
        parseTargetOrReferenceIdentifier();
        if (atToken(TokenKind.LPAREN)) {
          parseFuncallSuffix();
          marker.done(getFuncallExpressionType(tokenText));
        } else {
          marker.drop();
        }
        return;
      case TRUE: // intentional fall-through -- both treated as vanilla identifiers
      case FALSE:
        buildTokenElement(BuildElementTypes.BOOLEAN_LITERAL);
        return;
      case LBRACKET:
        parseListMaker();
        return;
      case LBRACE:
        parseDictExpression();
        return;
      case LPAREN:
        marker = builder.mark();
        builder.advanceLexer();
        if (matches(TokenKind.RPAREN)) {
          marker.done(BuildElementTypes.LIST_LITERAL);
          return;
        }
        parseExpression(true);
        expect(TokenKind.RPAREN, true);
        marker.done(BuildElementTypes.LIST_LITERAL);
        return;
      case MINUS:
        marker = builder.mark();
        builder.advanceLexer();
        parsePrimaryWithSuffix();
        marker.done(BuildElementTypes.POSITIONAL);
        return;
      default:
        builder.error("expected an expression");
        syncPast(EXPR_TERMINATOR_SET);
    }
  }

  /** funcall_suffix ::= '(' arg_list? ')' arg_list ::= ((arg ',')* arg ','? )? */
  private void parseFuncallSuffix() {
    PsiBuilder.Marker mark = builder.mark();
    expect(TokenKind.LPAREN, true);
    if (matches(TokenKind.RPAREN)) {
      mark.done(BuildElementTypes.ARGUMENT_LIST);
      return;
    }
    parseFuncallArgument();
    while (!atAnyOfTokens(FUNCALL_TERMINATOR_SET)) {
      expect(TokenKind.COMMA);
      if (atAnyOfTokens(FUNCALL_TERMINATOR_SET)) {
        break;
      }
      parseFuncallArgument();
    }
    expect(TokenKind.RPAREN, true);
    mark.done(BuildElementTypes.ARGUMENT_LIST);
  }

  private BuildElementType getFuncallExpressionType(String functionName) {
    if ("glob".equals(functionName)) {
      return BuildElementTypes.GLOB_EXPRESSION;
    }
    return BuildElementTypes.FUNCALL_EXPRESSION;
  }

  protected void parseFunctionParameters() {
    if (atToken(TokenKind.RPAREN)) {
      return;
    }
    parseFunctionParameter();
    while (!atAnyOfTokens(FUNCALL_TERMINATOR_SET)) {
      expect(TokenKind.COMMA);
      if (atAnyOfTokens(FUNCALL_TERMINATOR_SET)) {
        break;
      }
      parseFunctionParameter();
    }
  }

  // arg ::= IDENTIFIER '=' nontupleexpr
  //       | expr
  //       | *args
  //       | **kwargs
  private void parseFuncallArgument() {
    PsiBuilder.Marker marker = builder.mark();
    if (matches(TokenKind.STAR_STAR)) {
      parseNonTupleExpression();
      marker.done(BuildElementTypes.STAR_STAR);
      return;
    }
    if (matches(TokenKind.STAR)) {
      parseNonTupleExpression();
      marker.done(BuildElementTypes.STAR);
      return;
    }
    if (matchesSequence(TokenKind.IDENTIFIER, TokenKind.EQUALS)) {
      parseNonTupleExpression();
      marker.done(BuildElementTypes.KEYWORD);
      return;
    }
    parseNonTupleExpression();
    marker.done(BuildElementTypes.POSITIONAL);
  }

  /** arg ::= IDENTIFIER ['=' nontupleexpr] */
  private void parseFunctionParameter() {
    PsiBuilder.Marker marker = builder.mark();
    if (matches(TokenKind.STAR_STAR)) {
      expectIdentifier("invalid parameter name");
      marker.done(BuildElementTypes.PARAM_STAR_STAR);
      return;
    }
    if (matches(TokenKind.STAR)) {
      if (atToken(TokenKind.IDENTIFIER)) {
        builder.advanceLexer();
      }
      marker.done(BuildElementTypes.PARAM_STAR);
      return;
    }
    expectIdentifier("invalid parameter name");
    if (matches(TokenKind.EQUALS)) {
      parseNonTupleExpression();
      marker.done(BuildElementTypes.PARAM_OPTIONAL);
      return;
    }
    marker.done(BuildElementTypes.PARAM_MANDATORY);
  }

  protected void expectIdentifier(String error) {
    expect(TokenKind.IDENTIFIER, error, true);
  }

  // list_maker ::= '[' ']'
  //               |'[' expr ']'
  //               |'[' expr expr_list ']'
  //               |'[' expr ('FOR' loop_variables 'IN' expr)+ ']'
  private void parseListMaker() {
    PsiBuilder.Marker marker = builder.mark();
    expect(TokenKind.LBRACKET);
    if (matches(TokenKind.RBRACKET)) {
      marker.done(BuildElementTypes.LIST_LITERAL);
      return;
    }
    parseNonTupleExpression();
    switch (currentToken()) {
      case RBRACKET:
        builder.advanceLexer();
        marker.done(BuildElementTypes.LIST_LITERAL);
        return;
      case FOR:
        parseComprehensionSuffix(TokenKind.RBRACKET);
        marker.done(BuildElementTypes.LIST_COMPREHENSION_EXPR);
        return;
      case COMMA:
        parseExpressionList();
        if (!matches(TokenKind.RBRACKET)) {
          builder.error("expected 'for' or ']'");
          syncPast(LIST_TERMINATOR_SET);
        }
        marker.done(BuildElementTypes.LIST_LITERAL);
        return;
      default:
        builder.error("expected ',', 'for' or ']'");
        syncPast(LIST_TERMINATOR_SET);
        marker.done(BuildElementTypes.LIST_LITERAL);
    }
  }

  // dict_expression ::= '{' '}'
  //                    |'{' dict_entry_list '}'
  //                    |'{' dict_entry 'FOR' loop_variables 'IN' expr '}'
  private void parseDictExpression() {
    PsiBuilder.Marker marker = builder.mark();
    expect(TokenKind.LBRACE, true);
    if (matches(TokenKind.RBRACE)) {
      marker.done(BuildElementTypes.DICTIONARY_LITERAL);
      return;
    }
    parseDictEntry();
    if (currentToken() == TokenKind.FOR) {
      parseComprehensionSuffix(TokenKind.RBRACE);
      marker.done(BuildElementTypes.LIST_COMPREHENSION_EXPR);
      return;
    }
    if (matches(TokenKind.COMMA)) {
      parseDictEntryList();
    }
    expect(TokenKind.RBRACE, true);
    marker.done(BuildElementTypes.DICTIONARY_LITERAL);
  }

  // dict_entry_list ::= ( (dict_entry ',')* dict_entry ','? )?
  private void parseDictEntryList() {
    if (atAnyOfTokens(DICT_TERMINATOR_SET)) {
      return;
    }
    parseDictEntry();
    while (matches(TokenKind.COMMA)) {
      if (atAnyOfTokens(DICT_TERMINATOR_SET)) {
        return;
      }
      parseDictEntry();
    }
  }

  // dict_entry ::= nontupleexpr ':' nontupleexpr
  private void parseDictEntry() {
    PsiBuilder.Marker marker = builder.mark();
    parseNonTupleExpression();
    expect(TokenKind.COLON);
    parseNonTupleExpression();
    marker.done(BuildElementTypes.DICTIONARY_ENTRY_LITERAL);
  }

  // comprehension_suffix ::= 'FOR' loop_variables 'IN' expr comprehension_suffix
  //                        | 'IF' expr comprehension_suffix
  //                        | ']'
  private void parseComprehensionSuffix(TokenKind closingBracket) {
    while (true) {
      if (matches(TokenKind.FOR)) {
        parseForLoopVariables();
        expect(TokenKind.IN);
        parseNonTupleExpression(0);
      } else if (matches(TokenKind.IF)) {
        parseExpression(true);
      } else if (matches(closingBracket)) {
        return;
      } else {
        builder.error("expected " + closingBracket + ", 'for' or 'if'");
        syncPast(EXPR_LIST_TERMINATOR_SET);
        return;
      }
    }
  }

  // Equivalent to 'exprlist' rule in Python grammar.
  // loop_variables ::= primary_with_suffix ( ',' primary_with_suffix )* ','?
  protected void parseForLoopVariables() {
    PsiBuilder.Marker marker = builder.mark();
    parsePrimaryWithSuffix();
    if (currentToken() != TokenKind.COMMA) {
      marker.drop();
      return;
    }
    while (matches(TokenKind.COMMA)) {
      if (atAnyOfTokens(EXPR_LIST_TERMINATOR_SET)) {
        break;
      }
      parsePrimaryWithSuffix();
    }
    marker.done(BuildElementTypes.LIST_LITERAL);
  }
}
