/*
 * 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.
 */
package org.apache.drill.exec.expr.fn;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.List;

import org.apache.drill.common.exceptions.DrillRuntimeException;
import org.apache.drill.common.expression.FunctionHolderExpression;
import org.apache.drill.common.types.TypeProtos.DataMode;
import org.apache.drill.common.types.TypeProtos.MajorType;
import org.apache.drill.exec.expr.ClassGenerator;
import org.apache.drill.exec.expr.ClassGenerator.BlockType;
import org.apache.drill.exec.expr.ClassGenerator.HoldingContainer;
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
import org.apache.drill.exec.vector.ValueHolderHelper;

import com.sun.codemodel.JBlock;
import com.sun.codemodel.JConditional;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JExpression;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JOp;
import com.sun.codemodel.JVar;

/**
 * Definition of a Drill function defined using the
 * <code>@FunctionTemplate</code> annotation of the class which
 * implements the function. Simple functions have
 * input parameters as defined by member variables annotated
 * with the <code>@Param</code> annotation.
 */
public class DrillSimpleFuncHolder extends DrillFuncHolder {

  private final String drillFuncClass;
  // each function should be wrapped unique class loader associated with its jar
  // to prevent classpath collisions during loading and unloading jars
  private final ClassLoader classLoader;

  public DrillSimpleFuncHolder(FunctionAttributes functionAttributes, FunctionInitializer initializer) {
    super(functionAttributes, initializer);
    drillFuncClass = checkNotNull(initializer.getClassName());
    classLoader = checkNotNull(initializer.getClassLoader());
  }

  private String setupBody() {
    return meth("setup", false);
  }

  private String evalBody() {
    return meth("eval");
  }

  private String resetBody() {
    return meth("reset", false);
  }

  private String cleanupBody() {
    return meth("cleanup", false);
  }

  @Override
  public boolean isNested() {
    return false;
  }

  public DrillSimpleFunc createInterpreter() throws Exception {
    return (DrillSimpleFunc)Class.forName(drillFuncClass, true, classLoader).newInstance();
  }

  /**
   * Render the various code blocks for a simple function.
   *
   * @param classGenerator code generator
   * @param inputVariables value holder references for each input value. Variables
   * are in the same order as the declared function parameters
   * @param workspaceJVars internal working variables as declared with the
   * <code>@Workspece</code> annotations. These are simple variables, not
   * Drill value holders
   * @param holderExpr the function call expression
   */
  @Override
  public HoldingContainer renderEnd(ClassGenerator<?> classGenerator, HoldingContainer[] inputVariables,
                                    JVar[] workspaceJVars, FunctionHolderExpression holderExpr) {

    // If the function's annotation specifies a parameter has to be constant
    // expression, but the HoldingContainer for the argument is not, then raise
    // exception.
    for (int i = 0; i < inputVariables.length; i++) {
      if (getAttributeParameter(i).isConstant() && !inputVariables[i].isConstant()) {
        throw new DrillRuntimeException(String.format(
            "The argument '%s' of Function '%s' has to be constant!",
            getAttributeParameter(i).getName(), this.getRegisteredNames()[0]));
      }
    }
    // Inline code from the function's setup block
    generateBody(classGenerator, BlockType.SETUP, setupBody(), inputVariables, workspaceJVars, true);

    // Generate the wrapper, and inline code for, the function's eval block
    HoldingContainer c = generateEvalBody(classGenerator, inputVariables, evalBody(), workspaceJVars, holderExpr);

    // Generate code for an aggregate functions reset block
    generateBody(classGenerator, BlockType.RESET, resetBody(), null, workspaceJVars, false);

    // Inline code from the function's cleanup() method
    generateBody(classGenerator, BlockType.CLEANUP, cleanupBody(), null, workspaceJVars, false);
    return c;
  }

  /**
   * Generate the eval block for a simple function, including the null-handling wrapper,
   * if requested.
   *
   * @see {@link #generateBody()}
   */
  protected HoldingContainer generateEvalBody(ClassGenerator<?> g, HoldingContainer[] inputVariables, String body,
                                              JVar[] workspaceJVars, FunctionHolderExpression holderExpr) {

    g.getEvalBlock().directStatement(String.format(
        "//---- start of eval portion of %s function. ----//", getRegisteredNames()[0]));

    JBlock sub = new JBlock(true, true);
    JBlock topSub = sub;
    HoldingContainer out = null;
    MajorType returnValueType = getReturnType();

    // add outside null handling if it is defined.
    // If defined, the actual eval is in the "else" block of the
    // null checks.
    if (getNullHandling() == NullHandling.NULL_IF_NULL) {
      JExpression e = null;
      for (HoldingContainer v : inputVariables) {
        if (v.isOptional()) {
          JExpression isNullExpr;
          if (v.isReader()) {
            isNullExpr = JOp.cond(v.getHolder().invoke("isSet"), JExpr.lit(1), JExpr.lit(0));
          } else {
            isNullExpr = v.getIsSet();
          }
          if (e == null) {
            e = isNullExpr;
          } else {
            e = e.mul(isNullExpr);
          }
        }
      }

      if (e != null) {
        // if at least one expression must be checked, set up the conditional.
        returnValueType = getReturnType().toBuilder().setMode(DataMode.OPTIONAL).build();
        out = g.declare(returnValueType);
        e = e.eq(JExpr.lit(0));
        JConditional jc = sub._if(e);
        jc._then().assign(out.getIsSet(), JExpr.lit(0));
        sub = jc._else();
      } else if (holderExpr.getMajorType().getMode() == DataMode.OPTIONAL) {
        returnValueType = getReturnType().toBuilder().setMode(DataMode.OPTIONAL).build();
      }
    }

    if (out == null) {
      out = g.declare(returnValueType);
    }

    // add the subblock after the out declaration.
    g.getEvalBlock().add(topSub);

    JVar internalOutput = sub.decl(JMod.FINAL, g.getHolderType(returnValueType),
        getReturnValue().getName(), JExpr._new(g.getHolderType(returnValueType)));

    // Generate function body from source, including fields rendered as
    // block local vars.
    addProtectedBlock(g, sub, body, inputVariables, workspaceJVars, false);

    // Copy the output from the internal output parameter to the
    // one known in the outer scope.
    List<String> holderFields = ValueHolderHelper.getHolderParams(returnValueType);
    for (String holderField : holderFields) {
      sub.assign(out.f(holderField), internalOutput.ref(holderField));
    }

    if (sub != topSub) {
      sub.assign(out.f("isSet"), JExpr.lit(1));  // Assign null if NULL_IF_NULL mode
    }

    g.getEvalBlock().directStatement(String.format(
        "//---- end of eval portion of %s function. ----//", getRegisteredNames()[0]));

    return out;
  }
}
