//
// 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();
        VarIdentifier var = new VarIdentifier();
        varExp.setVar(var);
        var.setValue("$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;
    }
}