/*
 * Copyright 2008 Google Inc.
 *
 * 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.gwt.dev.jjs.impl;

import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JArrayLength;
import com.google.gwt.dev.jjs.ast.JArrayRef;
import com.google.gwt.dev.jjs.ast.JArrayType;
import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JBlock;
import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JForStatement;
import com.google.gwt.dev.jjs.ast.JIntLiteral;
import com.google.gwt.dev.jjs.ast.JLocal;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodBody;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
import com.google.gwt.dev.jjs.ast.JNewArray;
import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JParameterRef;
import com.google.gwt.dev.jjs.ast.JPostfixOperation;
import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JStatement;
import com.google.gwt.dev.jjs.ast.JUnaryOperation;
import com.google.gwt.dev.jjs.ast.JUnaryOperator;
import com.google.gwt.dev.jjs.ast.JVariableRef;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.RuntimeConstants;
import com.google.gwt.thirdparty.guava.common.collect.Iterables;

import java.util.Collections;

/**
 * Implements JavaScript varargs calling convention by rewriting varargs calls and adding a
 * prolog to varargs JsMethods.
 * <p>
 * At the calls sites, inline array creation is replaced by array literals, which in turn will be
 * unwrapped as individual parameters at generation time.
 * <p>
 * To implement varargs methods, we analyze the usage of the varargs parameter to determine whether
 * it can be accessed directly (with possibly an offset in the index) or it has to be copied.
 */
public class ImplementJsVarargs {
  /**
   * Analyzes a method body to check whether the varargs parameter can be used directly or not.
   * <p>
   * The arguments variable cannot be used directly if is referenced without indexing or accessing
   * its length, or if it is written to.
   */
  private class NeedsArgumentsCopyAnalyzer extends JVisitor {

    private VarargsProcessingResult result = VarargsProcessingResult.SIMPLE_ACCESS;
    private JParameter varargsParameter;
    private int varargsParameterIndex;

    private NeedsArgumentsCopyAnalyzer(JMethod method) {
      assert method.isJsMethodVarargs();
      this.varargsParameter = Iterables.getLast(method.getParams());
      this.varargsParameterIndex = method.getParams().size() - 1;
      if (varargsParameterIndex != 0) {
        upgradeResult(VarargsProcessingResult.OFFSET_ACCESS);
      }
    }

    @Override
    public void endVisit(JParameterRef x, Context ctx) {
      // Any reference that is not .length or indexed means that we need to copy the varargs array.
      if (isVarargsReference(x)) {
        upgradeResult(VarargsProcessingResult.GENERAL_ACCESS);
      }
    }

    @Override
    public boolean visit(JArrayLength x, Context ctx) {
      if (isVarargsReference(x.getInstance())) {
        // This is a safe reference.
        return false;
      }
      return true;
    }

    @Override
    public boolean visit(JArrayRef x, Context ctx) {
      if (isVarargsReference(x.getInstance())) {
        // This is a safe reference, so only check the index expression.
        accept(x.getIndexExpr());
        return false;
      }

      return true;
    }

    @Override
    public boolean visit(JBinaryOperation x, Context ctx) {
      if (isModifyingVarargs(x)) {
          // The varargs parameter is written to, so upgrade to copy.
          upgradeResult(VarargsProcessingResult.GENERAL_ACCESS);
        return false;
      }
      return true;
    }

    @Override
    public boolean visit(JUnaryOperation x, Context ctx) {
      if (isModifyingVarargs(x)) {
        // The varargs parameter is written to, so upgrade to copy.
        upgradeResult(VarargsProcessingResult.GENERAL_ACCESS);
        return false;
      }
      return true;
    }

    @Override
    public boolean visit(JMethodCall x, Context ctx) {
      // Allow
      if (x.getTarget().isJsMethodVarargs() && x.getArgs().size() == 1
          && isVarargsReference(x.getArgs().get(0))) {
        // The varargs parameter is passed directly and it is the only parameter, so if it is the
        // only parameter in the current method it can be passed directly.
        upgradeResult(VarargsProcessingResult.PASS_WHOLE);
        if (x.getInstance() != null) {
          accept(x.getInstance());
        }
        for (JExpression arg : x.getArgs().subList(1, x.getArgs().size())) {
          accept(arg);
        }
        return false;
      }
      return true;
    }

    private boolean isModifyingVarargs(JBinaryOperation x) {
      if (!x.getOp().isAssignment()) {
        return false;
      }
      if (!(x.getLhs() instanceof JArrayRef)) {
        return false;
      }
      JArrayRef arrayRef = (JArrayRef) x.getLhs();
      JExpression instance = arrayRef.getInstance();
      return isVarargsReference(instance);
    }

    private boolean isModifyingVarargs(JUnaryOperation x) {
      if (!x.getOp().isModifying()) {
        return false;
      }
      if (!(x.getArg() instanceof JArrayRef)) {
        return false;
      }
      JArrayRef arrayRef = (JArrayRef) x.getArg();
      JExpression instance = arrayRef.getInstance();
      return isVarargsReference(instance);
    }

    private boolean isVarargsReference(JExpression instance) {
      if (!(instance instanceof JParameterRef)) {
        return false;
      }

      return (((JParameterRef) instance).getTarget() == varargsParameter);
    }

    private void upgradeResult(VarargsProcessingResult upgradeTo) {
      result = VarargsProcessingResult.join(result, upgradeTo);
    }
  }

  // Defines the analysis lattice
  //                            SIMPLE_ACCESS   (only arguments[i] or arguments.length, no writing)
  //                               /        \
  //  (complete passing of        /          \
  //   arguments)           PASS_WHOLE  OFFSET_ACCESS   (Simple access but needs to offset index)
  //                              \         /
  //                               \       /
  //                             GENERAL_ACCESS
  //
  private enum VarargsProcessingResult {
    SIMPLE_ACCESS, PASS_WHOLE, OFFSET_ACCESS, GENERAL_ACCESS;

    private static VarargsProcessingResult join(
        VarargsProcessingResult thisResult, VarargsProcessingResult thatResult) {
      if (thisResult.ordinal() > thatResult.ordinal()) {
        VarargsProcessingResult swap = thisResult;
        thisResult = thatResult;
        thatResult = swap;
      }

      if ((thisResult == PASS_WHOLE &&  thatResult == OFFSET_ACCESS)) {
        return GENERAL_ACCESS;
      }
      return thatResult;
    }
  }

  private VarargsProcessingResult needsVarargsProcessing(JMethod method) {
    NeedsArgumentsCopyAnalyzer analyzer =  new NeedsArgumentsCopyAnalyzer(method);
    analyzer.accept(method);
    return analyzer.result;
  }

  private abstract class VarargsReplacer {
    abstract JExpression replace(JParameterRef expression);

    JExpression replace(JArrayRef expression) {
      return new JArrayRef(expression.getSourceInfo(),
          replace((JParameterRef)  expression.getInstance()),
          expression.getIndexExpr());
    }

    JExpression replace(JArrayLength expression) {
      return new JArrayLength(expression.getSourceInfo(),
          replace((JParameterRef)  expression.getInstance()));
    }
  }

  /**
   * Replaces varargs parameter accesses with accesses to the copy.
   */
  private class ReplaceVarargsVariable extends VarargsReplacer {
    private JLocal localVariable;
    ReplaceVarargsVariable(JLocal localVariable) {
      this.localVariable = localVariable;
    }

    @Override
    public JExpression replace(JParameterRef expression) {
      return localVariable.createRef(expression.getSourceInfo());
    }
  }

  /**
   * Fixes this indexing of vararg accesses.
   */
  private class ReindexAccess extends VarargsReplacer {
    private int varargsIndex;
    ReindexAccess(int varargsIndex) {
      this.varargsIndex = varargsIndex;
    }

    @Override
    public JExpression replace(JParameterRef expression) {
      return expression;
    }

    JExpression replace(JArrayRef expression) {
      SourceInfo sourceInfo = expression.getSourceInfo();
      return new JArrayRef(expression.getSourceInfo(),
          expression.getInstance(),
          new JBinaryOperation(sourceInfo, JPrimitiveType.INT, JBinaryOperator.ADD,
              expression.getIndexExpr(), new JIntLiteral(sourceInfo, varargsIndex)));
    }

    JExpression replace(JArrayLength expression) {
      SourceInfo sourceInfo = expression.getSourceInfo();
      return new JBinaryOperation(sourceInfo, JPrimitiveType.INT, JBinaryOperator.SUB,
              expression, new JIntLiteral(sourceInfo, varargsIndex));
    }
  }

  private class VarargsMethodNormalizer extends JModVisitor {
    private JParameter varargsParameter;
    private int varargsIndex;
    private VarargsReplacer replacer;
    private JLocal argumentsCopyVariable;

    @Override
    public boolean visit(JMethod x, Context ctx) {
      if (!x.isJsMethodVarargs()) {
        return false;
      }
      varargsParameter = Iterables.getLast(x.getParams());
      varargsIndex = x.getParams().size() - 1;

      // JsVarargs parameter can be assumend not null in the implementing method
      varargsParameter.setType(varargsParameter.getType().strengthenToNonNull());

      argumentsCopyVariable = null;
      switch (needsVarargsProcessing(x)) {
        case GENERAL_ACCESS:
          argumentsCopyVariable = JProgram.createLocal(varargsParameter.getSourceInfo(),
              varargsParameter.getName(), varargsParameter.getType(), false,
              (JMethodBody) x.getBody());
          replacer = new ReplaceVarargsVariable(argumentsCopyVariable);
          return true;
        case OFFSET_ACCESS:
          replacer = new ReindexAccess(varargsIndex);
          return true;
       default:
          return false;
      }
    }

    @Override
    public void endVisit(JParameterRef x, Context ctx) {
      if (x.getTarget() == varargsParameter) {
        maybeReplace(x, replacer.replace(x), ctx);
      }
    }

    @Override
    public void endVisit(JArrayRef x, Context ctx) {
      if (x.getInstance() instanceof JParameterRef
          && ((JParameterRef) x.getInstance()).getTarget() == varargsParameter) {
        maybeReplace(x, replacer.replace(x), ctx);
      }
    }

    @Override
    public void endVisit(JArrayLength x, Context ctx) {
      if (x.getInstance() instanceof JParameterRef
          && ((JParameterRef) x.getInstance()).getTarget() == varargsParameter) {
        maybeReplace(x, replacer.replace(x), ctx);
      }
    }

    @Override
    public void endVisit(JMethod x, Context ctx) {
      if (!x.isJsMethodVarargs()) {
        return;
      }
      // rename the varargs variable to _arguments_.
      varargsParameter.setName("_arguments_");
    }

    private void maybeReplace(JExpression x, JExpression replacement, Context ctx) {
      if (replacement != x) {
        ctx.replaceMe(replacement);
      }
    }

    @Override
    public void endVisit(JMethodBody x, Context ctx) {
      if (argumentsCopyVariable == null) {
        return;
      }

      // Needs to populate the copy; add preamble.
      //
      // {
      //   <Type>[] args = new <Type>[arguments.length - offset];
      //   for (int $i = 0; $i < arguments.length - offset; i++) {
      //     args[i] = arguments[i + offset];
      //   }
      // }

      SourceInfo sourceInfo = varargsParameter.getSourceInfo();
      JBlock preamble = new JBlock(sourceInfo);
      JArrayType varargsArrayType = (JArrayType) varargsParameter.getType().getUnderlyingType();

      // (1) varargs_ = new VarArgsType[varargs.length - varArgsParameterIndex]
      JExpression lengthMinusVarargsIndex = varargsIndex == 0
          ? new JArrayLength(sourceInfo, varargsParameter.createRef(sourceInfo))
          : new JBinaryOperation(sourceInfo, JPrimitiveType.INT, JBinaryOperator.SUB,
              new JArrayLength(sourceInfo, varargsParameter.createRef(sourceInfo)),
              new JIntLiteral(sourceInfo, varargsIndex));
      JNewArray arrayVariable = JNewArray.createArrayWithDimensionExpressions(sourceInfo,
          varargsArrayType, Collections.singletonList(lengthMinusVarargsIndex));
      arrayVariable.getLeafTypeClassLiteral().setField(
          program.getClassLiteralField(varargsArrayType.getLeafType()));
      preamble.addStmt(new JDeclarationStatement(
          sourceInfo, argumentsCopyVariable.createRef(sourceInfo), arrayVariable));

      JLocal index = JProgram.createLocal(sourceInfo, "$i", JPrimitiveType.INT, false, x);

      // (2) (copy loop body)  varargs_[i] = varargs[i + varargsIndex];
      JExpression iPlusVarargsIndex = varargsIndex == 0 ? index.createRef(sourceInfo)
          : new JBinaryOperation(sourceInfo, JPrimitiveType.INT, JBinaryOperator.ADD,
              index.createRef(sourceInfo), new JIntLiteral(sourceInfo, varargsIndex));

      JBlock block = new JBlock(sourceInfo);
      block.addStmt(new JBinaryOperation(
          sourceInfo,
          varargsArrayType.getElementType(),
          JBinaryOperator.ASG,
          new JArrayRef(sourceInfo, replacer.replace(varargsParameter.createRef(sourceInfo)),
              index.createRef(sourceInfo)),
          new JArrayRef(sourceInfo, varargsParameter.createRef(sourceInfo), iPlusVarargsIndex))
              .makeStatement());
      // (3) for (int $i = 0 ; i < arguments.length - index; i++) {
      //       varargs_[i] = varargs[i + varargsIndex];
      //     }
      preamble.addStmt(new JForStatement(sourceInfo, Collections.<JStatement>singletonList(
          new JDeclarationStatement(sourceInfo, index.createRef(sourceInfo), JIntLiteral.ZERO)),
          new JBinaryOperation(sourceInfo, JPrimitiveType.INT,JBinaryOperator.LT,
                  index.createRef(sourceInfo),
              new CloneExpressionVisitor().cloneExpression(lengthMinusVarargsIndex)),
          new JPostfixOperation(sourceInfo, JUnaryOperator.INC, index.createRef(sourceInfo)),
          block));
      x.getStatements().add(0, preamble);
    }
  }

  // Normalizes JsVarargsCalls so that
  //  (1) inline new array expressions resulting from a "regular" varargs invocation are replaced
  //      by plain array literals.
  //  (2) side effecting instances in JsVarargs instance method calls with array calling convention
  //      are hoited into temporary variables.
  private class VarargsCallsNormalizer extends JModVisitor {
    private JMethodBody currentMethodBody;

    @Override
    public boolean visit(JMethodBody x, Context ctx) {
      currentMethodBody = x;
      return true;
    }

    @Override
    public void endVisit(JMethodBody x, Context ctx) {
      currentMethodBody = null;
    }

    @Override
    public void endVisit(JMethodCall x, Context ctx) {
      JMethod method = x.getTarget();
      if (!method.isJsMethodVarargs()) {
        return;
      }

      int varargIndex = method.getParams().size() - 1;
      JExpression varargArgument = x.getArgs().get(varargIndex);
      if (varargArgument instanceof JNewArray) {
        JNewArray varargArray = (JNewArray) varargArgument;
        if (varargArray.getInitializers() != null) {
          x.setArg(varargIndex, ArrayNormalizer.getInitializerArray(varargArray));
          madeChanges();
          return;
        }
      }

      SourceInfo varargsArgumentsourceInfo = varargArgument.getSourceInfo();
      if (varargArgument.getType().canBeNull()) {
        // varargsArgument => Array.ensureNotNull(varargsArgument)
        x.setArg(varargIndex, new JMethodCall(varargsArgumentsourceInfo, null,
            program.getIndexedMethod(RuntimeConstants.ARRAY_ENSURE_NOT_NULL), varargArgument));
      }

      // Passed as an array to varargs method will result in an apply call, in which case hoist the
      // qualifier to make sure it is only evaluated once.
      JExpression instance = x.getInstance();
      if (x.getTarget().needsDynamicDispatch() && !x.isStaticDispatchOnly()
          && instance != null && !(instance instanceof JVariableRef)) {
        // Move the potentially sideffecting qualifier to a temporary variable so that
        // the code generation for calls that need .apply don't need to hande the case.
        SourceInfo sourceInfo = x.getSourceInfo();
        JLocal tempInstance = JProgram.createLocal(sourceInfo, "$instance",
            instance.getType(), false, currentMethodBody);
        // (tempInstance = instance,
        //  tempInstance.method(pars);
        ctx.replaceMe(JjsUtils.createOptimizedMultiExpression(
            new JBinaryOperation(sourceInfo, instance.getType(),
                JBinaryOperator.ASG, tempInstance.createRef(sourceInfo), instance),
            new JMethodCall(x, tempInstance.createRef(sourceInfo), x.getArgs())));
      }
    }
  }

  public static void exec(JProgram program) {
    new ImplementJsVarargs(program).execImpl();
  }

  private final JProgram program;

  private ImplementJsVarargs(JProgram program) {
    this.program = program;
  }

  private void execImpl() {
    new VarargsMethodNormalizer().accept(program);
    new VarargsCallsNormalizer().accept(program);
  }
}
