//
// 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.
//

import org.apache.asterix.bad.lang.statement.BrokerDropStatement;
import org.apache.asterix.bad.lang.statement.ChannelDropStatement;
import org.apache.asterix.bad.lang.statement.ChannelSubscribeStatement;
import org.apache.asterix.bad.lang.statement.ChannelUnsubscribeStatement;
import org.apache.asterix.bad.lang.statement.CreateBrokerStatement;
import org.apache.asterix.bad.lang.statement.CreateChannelStatement;
import org.apache.asterix.bad.lang.statement.CreateProcedureStatement;
import org.apache.asterix.bad.lang.statement.ExecuteProcedureStatement;
import org.apache.asterix.bad.lang.statement.ProcedureDropStatement;
import org.apache.asterix.lang.sqlpp.parser.ParseException;
import org.apache.asterix.lang.sqlpp.parser.SqlppParseException;
import org.apache.asterix.lang.sqlpp.parser.Token;


@merge
Statement SingleStatement() throws ParseException:
{
  // merge area 1
  before:
  after:
}
{
  (
    // merge area 2
    before:
    after:    | stmt = ChannelSubscriptionStatement() | stmt = ProcedureExecution())
  {
    // merge area 3
  }
}

@merge
Statement CreateStatement() throws ParseException:
{
  // merge area 1
  before:
  after:
}
{
  (
    // merge area 2
    before:
    after:    | stmt = ChannelSpecification() | stmt = BrokerSpecification() | stmt = ProcedureSpecification())
  {
    // merge area 3
  }
}

@merge
Statement DropStatement() throws ParseException:
{
  // merge area 1
  before:
  after:
}
{
  (
    // merge area 2
    before:
    after:    | "channel" pairId = QualifiedName() ifExists = IfExists()
      {
        stmt = new ChannelDropStatement(pairId.first, pairId.second, ifExists);
      }
              | "broker" pairId = QualifiedName() ifExists = IfExists()
      {
        stmt = new BrokerDropStatement(pairId.first, pairId.second, ifExists);
      }
              | "procedure" funcSig = FunctionSignature() ifExists = IfExists()
      {
        stmt = new ProcedureDropStatement(funcSig, ifExists);
      }
      )
  {
    // merge area 3
  }
}

@new
CreateChannelStatement ChannelSpecification() throws ParseException:
{
  Pair<Identifier,Identifier> nameComponents = null;
  FunctionSignature appliedFunction = null;
  CreateChannelStatement ccs = null;
  String fqFunctionName = null;
  Expression period = null;
  boolean push = false;
}
{
  (
    "repetitive"
    ( "push" { push = true; } )?
     "channel"  nameComponents = QualifiedName()
    <USING> appliedFunction = FunctionSignature()
    "period" period = FunctionCallExpr()
    {
      ccs = new CreateChannelStatement(nameComponents.first,
                                   nameComponents.second, appliedFunction, period, push);
    }
  )
    {
      return ccs;
    }
}

@new
CreateProcedureStatement ProcedureSpecification() throws ParseException:
{
  FunctionName fctName = null;
  FunctionSignature signature;
  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
  List<Integer> paramIds = new ArrayList<Integer>();
  String functionBody;
  Token beginPos;
  Token endPos;
  Statement functionBodyExpr;
  Expression period = null;
  String currentDataverse = defaultDataverse;
  createNewScope();
}
{
     "procedure" fctName = FunctionName()
     {
        defaultDataverse = fctName.dataverse;
     }
     paramList = ParameterList()
    <LEFTBRACE>
  {
    for (VarIdentifier param : paramList)
    {
      VarIdentifier v = new VarIdentifier(param.toString());
      getCurrentScope().addNewVarSymbolToScope(v);
      paramIds.add(v.getId());
    }
    beginPos = token;
  }
  functionBodyExpr = SingleStatement() <RIGHTBRACE>
    {
      endPos = token;
      functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
      signature = new FunctionSignature(fctName.dataverse, fctName.function, paramList.size());
      removeCurrentScope();
      defaultDataverse = currentDataverse;
    }
  ("period" period = FunctionCallExpr())?
  {
  return new CreateProcedureStatement(signature, paramList, paramIds, functionBody, period);
  }
}

@new
ExecuteProcedureStatement ProcedureExecution() throws ParseException:
{
  ExecuteProcedureStatement callExpr;
  List<Expression> argList = new ArrayList<Expression>();
  Expression tmp;
  int arity = 0;
  FunctionName funcName = null;
  String hint = null;
}
{
  "execute"
  funcName = FunctionName()
  <LEFTPAREN> (tmp = Expression()
    {
      argList.add(tmp);
      arity ++;
    }
  (<COMMA> tmp = Expression()
    {
      argList.add(tmp);
      arity++;
    }
  )*)? <RIGHTPAREN>
    {
      String fqFunctionName =  funcName.function;
      return new ExecuteProcedureStatement(funcName.dataverse, fqFunctionName, arity, argList);
    }
}

@new
CreateBrokerStatement BrokerSpecification() throws ParseException:
{
  CreateBrokerStatement cbs = null;
  Pair<Identifier,Identifier> name = null;
  String endPoint = null;
}
{
  (
    "broker"  name = QualifiedName()
    <AT>  endPoint = StringLiteral()
    {
      cbs = new CreateBrokerStatement(name.first, name.second,endPoint);
    }
  )
    {
      return cbs;
    }
}

@new
Statement ChannelSubscriptionStatement() throws ParseException:
{
  Statement stmt = null;
  Pair<Identifier,Identifier> nameComponents = null;
  List<Expression> argList = new ArrayList<Expression>();
  Expression tmp = null;
  String id = null;
  String subscriptionId = null;
  Pair<Identifier,Identifier> brokerName = null;
}
{
  (
  "subscribe" <TO> nameComponents = QualifiedName()
   <LEFTPAREN> (tmp = Expression()
   {
      argList.add(tmp);
   }
   (<COMMA> tmp = Expression()
   {
      argList.add(tmp);
   }
   )*)? <RIGHTPAREN> <ON> brokerName = QualifiedName()
   {
      stmt = new ChannelSubscribeStatement(nameComponents.first, nameComponents.second, argList, getVarCounter(), brokerName.first, brokerName.second, subscriptionId);
   }
   | "unsubscribe" id = StringLiteral() <FROM> nameComponents = QualifiedName()
      {
        VariableExpr varExp = new VariableExpr(new VarIdentifier("$subscriptionPlaceholder"));
        getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
        stmt = new ChannelUnsubscribeStatement(varExp, nameComponents.first, nameComponents.second, id, getVarCounter());
      }
     | "change" "subscription" subscriptionId = StringLiteral()  <ON> nameComponents = QualifiedName()
       <LEFTPAREN> (tmp = Expression()
       {
         argList.add(tmp);
       }
       (<COMMA> tmp = Expression()
       {
         argList.add(tmp);
       }
       )*)? <RIGHTPAREN>
        <TO> brokerName = QualifiedName()
      {
        stmt = new ChannelSubscribeStatement(nameComponents.first, nameComponents.second, argList, getVarCounter(), brokerName.first, brokerName.second, subscriptionId);
      }
    )
    {
      return stmt;
    }
}