/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

%skeleton "lalr1.cc"
%require "3.0"

%define api.namespace {org::apache::nifi::minifi::expression}
%parse-param {Driver* driver}
%locations

%define parser_class_name {Parser}
%define parse.error verbose
%define api.value.type variant
%define parse.assert
%define api.token.prefix {TOK_}

%code requires
{
  #include <string>

  #include "expression-language/Expression.h"
  #include "location.hh"
  #if defined(WIN32) && defined(S_FALSE)
  #undef S_FALSE  // winerror.h #defines S_FALSE, which conflicts with the generated token
  #endif

  namespace org::apache::nifi::minifi::expression {
    class Driver;
  }  // namespace org::apache::nifi::minifi::expression
}

%code
{
  #include <utility>
  #include <memory>
  #include <functional>

  #include "expression-language/Expression.h"
  #include "expression-language/Driver.h"

  #undef yylex
  #define yylex driver->lex
}

%token
  END 0          "eof"
  NEWLINE        "\n"
  DOLLAR         "$"
  LCURLY         "{"
  RCURLY         "}"
  LPAREN         "("
  RPAREN         ")"
  LSQUARE        "["
  RSQUARE        "]"
  PIPE           "|"
  MINUS          "-"
  COMMA          ","
  COLON          ":"
  SEMI           ";"
  FSLASH         "/"
  BSLASH         "\\"
  STAR           "*"
  HASH           "#"
  SQUOTE         "'"
  DQUOTE         "\""
;

%token <std::string> TRUE       "true"
%token <std::string> FALSE      "false"
%token <std::string> IDENTIFIER "identifier"
%token <std::string> MISC       "misc"
%token <std::string> WHITESPACE "whitespace"
%token <std::string> NUMBER     "number"

%type <std::string>             exp_whitespace
%type <std::string>             exp_whitespaces
%type <std::string>             attr_id
%type <Expression>              fn_call
%type <Expression>              fn_arg
%type <std::vector<Expression>> fn_args
%type <Expression>              exp_content
%type <Expression>              exp_content_val
%type <Expression>              exp
%type <Expression>              exps
%type <std::string>             text_no_quote_no_dollar
%type <std::string>             text_inc_quote_escaped_dollar
%type <std::string>             text_inc_dollar
%type <std::string>             quoted_text
%type <std::string>             quoted_text_content
%type <Expression>              text_or_exp

%type <std::vector<std::pair<std::string, std::vector<Expression>>>> fn_calls

%%

%start root;

root: exps { driver->result = $1; }
    ;

text_no_quote_no_dollar: IDENTIFIER { std::swap($$, $1); }
                       | WHITESPACE { std::swap($$, $1); }
                       | NEWLINE { $$ = "\n"; }
                       | MISC { std::swap($$, $1); }
                       | LCURLY { $$ = "{"; }
                       | RCURLY { $$ = "}"; }
                       | LPAREN { $$ = "("; }
                       | RPAREN { $$ = ")"; }
                       | LSQUARE { $$ = "["; }
                       | RSQUARE { $$ = "]"; }
                       | PIPE { $$ = "|"; }
                       | COMMA { $$ = ","; }
                       | COLON { $$ = ":"; }
                       | TRUE { $$ = std::string("true"); }
                       | FALSE { $$ = std::string("false"); }
                       | SEMI { $$ = ";"; }
                       | FSLASH { $$ = "/"; }
                       | STAR { $$ = "*"; }
                       | HASH { $$ = "#"; }
                       | NUMBER { std::swap($$, $1); }
                       ;

text_inc_quote_escaped_dollar: text_no_quote_no_dollar { std::swap($$, $1); }
                             | SQUOTE { $$ = "'"; }
                             | DQUOTE { $$ = "\""; }
                             | BSLASH { $$ = "\\"; }
                             | DOLLAR DOLLAR { $$ = "$"; }
                             ;

text_inc_dollar: text_no_quote_no_dollar { std::swap($$, $1); }
               | DOLLAR { $$ = "$"; }
               | BSLASH SQUOTE { $$ = "'"; }
               | BSLASH DQUOTE { $$ = "\""; }
               | BSLASH BSLASH { $$ = "\\"; }
               ;

quoted_text_content: %empty {}
                   | quoted_text_content text_inc_dollar { $$ = $1 + $2; }
                   ;

quoted_text: SQUOTE quoted_text_content SQUOTE { std::swap($$, $2); }
           | DQUOTE quoted_text_content DQUOTE { std::swap($$, $2); }
           ;

text_or_exp: text_inc_quote_escaped_dollar { $$ = make_static(std::move($1)); }
           | exp { $$ = $1; }
           ;

exps: %empty {}
    | exps text_or_exp { $$ = $1 + $2; }
    ;

exp_whitespace: WHITESPACE {}
              | NEWLINE {}
              ;

exp_whitespaces: %empty {}
               | exp_whitespaces exp_whitespace {}
               ;

attr_id: quoted_text exp_whitespaces { std::swap($$, $1); }
       | IDENTIFIER exp_whitespaces { std::swap($$, $1); }
       ;

fn_arg: quoted_text exp_whitespaces { $$ = make_static($1); }
      | NUMBER exp_whitespaces { $$ = make_static($1); }
      | TRUE { $$ = Expression(Value(true)); }
      | FALSE { $$ = Expression(Value(false)); }
      | exp exp_whitespaces { $$ = $1; }
      ;

fn_args: %empty {}
       | fn_args COMMA exp_whitespaces fn_arg { $$.insert($$.end(), $1.begin(), $1.end()); $$.push_back($4); }
       | fn_arg { $$.push_back($1); }

fn_call: attr_id LPAREN exp_whitespaces fn_args RPAREN exp_whitespaces { $$ = make_dynamic_function(std::move($1), $4); }

fn_calls: %empty {}
        | COLON exp_whitespaces attr_id LPAREN exp_whitespaces fn_args RPAREN exp_whitespaces fn_calls { $$.push_back({$3, $6}); $$.insert($$.end(), $9.begin(), $9.end()); }
        ;

exp_content_val: attr_id { $$ = make_dynamic_attr(std::move($1)); }
               | fn_call { $$ = $1; }
               ;

exp_content: exp_content_val fn_calls { $$ = make_function_composition($1, $2); }
           ;

exp: DOLLAR LCURLY exp_whitespaces exp_content RCURLY { $$ = $4; }
   ;

%%

void org::apache::nifi::minifi::expression::Parser::error(const location_type &location,
                                                          const std::string &message) {
  std::stringstream err_msg;
  err_msg << location;
  err_msg << ": ";
  err_msg << message;
  throw std::runtime_error(err_msg.str());
}
