/*
 * 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.compile.bytecode;

import java.util.HashMap;

import org.apache.drill.exec.compile.CompilationConfig;
import org.apache.drill.exec.compile.bytecode.ValueHolderIden.ValueHolderSub;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Frame;

import com.carrotsearch.hppc.IntIntHashMap;
import com.carrotsearch.hppc.IntObjectHashMap;
import com.carrotsearch.hppc.cursors.IntIntCursor;
import com.carrotsearch.hppc.cursors.IntObjectCursor;
import com.google.common.base.Preconditions;

public class InstructionModifier extends MethodVisitor {
  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(InstructionModifier.class);

  /* Map from old (reference) local variable index to new local variable information. */
  private final IntObjectHashMap<ValueHolderIden.ValueHolderSub> oldToNew = new IntObjectHashMap<>();

  private final IntIntHashMap oldLocalToFirst = new IntIntHashMap();

  private final DirectSorter adder;
  private int lastLineNumber = 0; // the last line number seen
  private final TrackingInstructionList list;
  private final String name;
  private final String desc;
  private final String signature;

  private int stackIncrease = 0; // how much larger we have to make the stack

  public InstructionModifier(final int access, final String name, final String desc,
      final String signature, final String[] exceptions, final TrackingInstructionList list,
      final MethodVisitor inner) {
    super(CompilationConfig.ASM_API_VERSION, new DirectSorter(access, desc, inner));
    this.name = name;
    this.desc = desc;
    this.signature = signature;
    this.list = list;
    this.adder = (DirectSorter) mv;
  }

  public int getLastLineNumber() {
    return lastLineNumber;
  }

  private static ReplacingBasicValue filterReplacement(final BasicValue basicValue) {
    if (basicValue instanceof ReplacingBasicValue) {
      final ReplacingBasicValue replacingValue = (ReplacingBasicValue) basicValue;
      if (replacingValue.isReplaceable()) {
        return replacingValue;
      }
    }

    return null;
  }

  private ReplacingBasicValue getLocal(final int var) {
    final BasicValue basicValue = list.currentFrame.getLocal(var);
    return filterReplacement(basicValue);
  }

  /**
   * Peek at a value in the current frame's stack, counting down from the top.
   *
   * @param depth how far down to peek; 0 is the top of the stack, 1 is the
   *   first element down, etc
   * @return the value on the stack, or null if it isn't a ReplacingBasciValue
   */
  private ReplacingBasicValue peekFromTop(final int depth) {
    Preconditions.checkArgument(depth >= 0);
    final Frame<BasicValue> frame = list.currentFrame;
    final BasicValue basicValue = frame.getStack((frame.getStackSize() - 1) - depth);
    return filterReplacement(basicValue);
  }

  /**
   * Get the value of a function return if it is a ReplacingBasicValue.
   *
   * <p>Assumes that we're in the middle of processing an INVOKExxx instruction.
   *
   * @return the value that will be on the top of the stack after the function returns
   */
  private ReplacingBasicValue getFunctionReturn() {
    final Frame<BasicValue> nextFrame = list.nextFrame;
    final BasicValue basicValue = nextFrame.getStack(nextFrame.getStackSize() - 1);
    return filterReplacement(basicValue);
  }

  @Override
  public void visitInsn(final int opcode) {
    switch (opcode) {
    case Opcodes.DUP:
      /*
       * Pattern:
       *   BigIntHolder out5 = new BigIntHolder();
       *
       * Original bytecode:
       *   NEW org/apache/drill/exec/expr/holders/BigIntHolder
       *   DUP
       *   INVOKESPECIAL org/apache/drill/exec/expr/holders/BigIntHolder.<init> ()V
       *   ASTORE 6 # the index of the out5 local variable (which is a reference)
       *
       * Desired replacement:
       *   ICONST_0
       *   ISTORE 12
       *
       *   In the original, the holder's objectref will be used twice: once for the
       *   constructor call, and then to be stored. Since the holder has been replaced
       *   with one or more locals to hold its members, we don't allocate or store it.
       *   he NEW and the ASTORE are replaced via some stateless changes elsewhere; here
       *   we need to eliminate the DUP.
       *
       * TODO: there may be other reasons for a DUP to appear in the instruction stream,
       * such as reuse of a common subexpression that the compiler optimizer has
       * eliminated. This pattern may also be used for non-holders. We need to be
       * more certain of the source of the DUP, and whether the surrounding context matches
       * the above.
       */
      if (peekFromTop(0) != null) {
        return; // don't emit the DUP
      }
      break;

    case Opcodes.DUP_X1: {
      /*
       * There are a number of patterns that lead to this instruction being generated. Here
       * are some examples:
       *
       * Pattern:
       *   129:        out.start = out.end = text.end;
       *
       * Original bytecode:
       *   L9
       *    LINENUMBER 129 L9
       *    ALOAD 7
       *    ALOAD 7
       *    ALOAD 8
       *    GETFIELD org/apache/drill/exec/expr/holders/VarCharHolder.end : I
       *    DUP_X1
       *    PUTFIELD org/apache/drill/exec/expr/holders/VarCharHolder.end : I
       *    PUTFIELD org/apache/drill/exec/expr/holders/VarCharHolder.start : I
       *
       * Desired replacement:
       *   L9
       *    LINENUMBER 129 L9
       *    ILOAD 17
       *    DUP
       *    ISTORE 14
       *    ISTORE 13
       *
       *    At this point, the ALOAD/GETFIELD and ALOAD/PUTFIELD combinations have
       *    been replaced by the ILOAD and ISTOREs. However, there is still the DUP_X1
       *    in the instruction stream. In this case, it is duping the fetched holder
       *    member so that it can be stored again. We still need to do that, but because
       *    the ALOADed objectrefs are no longer on the stack, we don't need to duplicate
       *    the value lower down in the stack anymore, but can instead DUP it where it is.
       *    (Similarly, if the fetched field was a long or double, the same applies for
       *    the expected DUP2_X1.)
       *
       * There's also a similar pattern for zeroing values:
       * Pattern:
       *   170:            out.start = out.end = 0;
       *
       * Original bytecode:
       *   L20
       *    LINENUMBER 170 L20
       *    ALOAD 13
       *    ALOAD 13
       *    ICONST_0
       *    DUP_X1
       *    PUTFIELD org/apache/drill/exec/expr/holders/VarCharHolder.end : I
       *    PUTFIELD org/apache/drill/exec/expr/holders/VarCharHolder.start : I
       *
       * Desired replacement:
       *   L20
       *    LINENUMBER 170 L20
       *    ICONST_0
       *    DUP
       *    ISTORE 17
       *    ISTORE 16
       *
       *
       * There's also another pattern that involves DUP_X1
       * Pattern:
       *   1177:                   out.buffer.setByte(out.end++, currentByte);
       *
       * We're primarily interested in the out.end++ -- the post-increment of
       * a holder member.
       *
       * Original bytecode:
       *    L694
       *     LINENUMBER 1177 L694
       *     ALOAD 212
       *     GETFIELD org/apache/drill/exec/expr/holders/VarCharHolder.buffer : Lio/netty/buffer/DrillBuf;
       *     ALOAD 212
       *     DUP
       * >   GETFIELD org/apache/drill/exec/expr/holders/VarCharHolder.end : I
       * >   DUP_X1
       * >   ICONST_1
       * >   IADD
       * >   PUTFIELD org/apache/drill/exec/expr/holders/VarCharHolder.end : I
       *     ILOAD 217
       *     INVOKEVIRTUAL io/netty/buffer/DrillBuf.setByte (II)Lio/netty/buffer/ByteBuf;
       *     POP
       *
       * This fragment includes the entirety of the line 1177 above, but we're only concerned with
       * the lines marked with '>' on the left; the rest were kept for context, because it is the
       * use of the pre-incremented value as a function argument that is generating the DUP_X1 --
       * the DUP_X1 is how the value is preserved before incrementing.
       *
       * The common element in these patterns is that the stack has an objectref and a value that will
       * be stored via a PUTFIELD. The value has to be used in other contexts, so it is to be DUPed, and
       * stashed away under the objectref. In the case where the objectref belongs to a holder that will
       * be gone as a result of scalar replacement, then the objectref won't be present, so we don't need
       * the _X1 option.
       *
       * If we're replacing the holder under the value being duplicated, then we don't need to put the
       * DUPed value back under it, because it won't be present in the stack. We can just use a plain DUP.
       */
      final ReplacingBasicValue rbValue = peekFromTop(1);
      if (rbValue != null) {
        super.visitInsn(Opcodes.DUP);
        return;
      }
      break;
    }

    case Opcodes.DUP2_X1: {
      /*
       * See the comments above for DUP_X1, which also apply here; this just handles long and double
       * values, which are twice as large, in the same way.
       */
      if (peekFromTop(0) != null) {
        throw new IllegalStateException("top of stack should be 2nd part of a long or double");
      }
      final ReplacingBasicValue rbValue = peekFromTop(2);
      if (rbValue != null) {
        super.visitInsn(Opcodes.DUP2);
        return;
      }
      break;
    }
    }

    // if we get here, emit the original instruction
    super.visitInsn(opcode);
  }

  @Override
  public void visitTypeInsn(final int opcode, final String type) {
    /*
     * This includes NEW, NEWARRAY, CHECKCAST, or INSTANCEOF.
     *
     * TODO: aren't we just trying to eliminate NEW (and possibly NEWARRAY)?
     * It looks like we'll currently pick those up because we'll only have
     * replaced the values for those, but we might find other reasons to replace
     * things, in which case this will be too broad.
     */
    final ReplacingBasicValue r = getFunctionReturn();
    if (r != null) {
      final ValueHolderSub sub = r.getIden().getHolderSub(adder);
      oldToNew.put(r.getIndex(), sub);
    } else {
      super.visitTypeInsn(opcode, type);
    }
  }

  @Override
  public void visitLineNumber(final int line, final Label start) {
    lastLineNumber = line;
    super.visitLineNumber(line, start);
  }

  @Override
  public void visitVarInsn(final int opcode, final int var) {
    ReplacingBasicValue v;
    if (opcode == Opcodes.ASTORE && (v = peekFromTop(0)) != null) {
      final ValueHolderSub from = oldToNew.get(v.getIndex());

      final ReplacingBasicValue current = getLocal(var);
      // if local var is set, then transfer to it to the existing holders in the local position.
      if (current != null) {
        final ValueHolderSub newSub = oldToNew.get(current.getIndex());
        if (newSub.iden() == from.iden()) {
          final int targetFirst = newSub.first();
          from.transfer(this, targetFirst);
          return;
        }
      }

      // if local var is not set, then check map to see if existing holders are mapped to local var.
      if (oldLocalToFirst.containsKey(var)) {
        final ValueHolderSub sub = oldToNew.get(oldLocalToFirst.get(var));
        if (sub.iden() == from.iden()) {
          // if they are, then transfer to that.
          from.transfer(this, sub.first());
          return;
        }
      }

      // map from variables to global space for future use.
      oldLocalToFirst.put(var, v.getIndex());
      return;
    } else if (opcode == Opcodes.ALOAD && (v = getLocal(var)) != null) {
      /*
       * Not forwarding this removes a now unnecessary ALOAD for a holder. The required LOAD/STORE
       * sequences will be generated by the ASTORE code above.
       */
      return;
    }

    super.visitVarInsn(opcode, var);
  }

  void directVarInsn(final int opcode, final int var) {
    adder.directVarInsn(opcode, var);
  }

  @Override
  public void visitMaxs(final int maxStack, final int maxLocals) {
    super.visitMaxs(maxStack + stackIncrease, maxLocals);
  }

  @Override
  public void visitFieldInsn(final int opcode, final String owner,
      final String name, final String desc) {
    int stackDepth = 0;
    ReplacingBasicValue value;
    switch (opcode) {
    case Opcodes.PUTFIELD:
      value = peekFromTop(stackDepth++);
      if (value != null) {
        if (filterReplacement(value) == null) {
          super.visitFieldInsn(opcode, owner, name, desc);
          return;
        } else {
          /*
           * We are trying to store a replaced variable in an external context,
           * we need to generate an instance and transfer it out.
           */
          final ValueHolderSub sub = oldToNew.get(value.getIndex());
          final int additionalStack = sub.transferToExternal(adder, owner, name, desc);
          if (additionalStack > stackIncrease) {
            stackIncrease = additionalStack;
          }
          return;
        }
      }
      // $FALL-THROUGH$

    case Opcodes.GETFIELD:
      // if falling through from PUTFIELD, this gets the 2nd item down
      value = peekFromTop(stackDepth);
      if (value != null) {
        if (filterReplacement(value) != null) {
          final ValueHolderSub sub = oldToNew.get(value.getIndex());
          if (sub != null) {
            sub.addInsn(name, this, opcode);
            return;
          }
        }
      }
      /* FALLTHROUGH */
    }

    // if we get here, emit the field reference as-is
    super.visitFieldInsn(opcode, owner, name, desc);
  }

  @Override
  public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
    /*
     * This method was deprecated in the switch from api version ASM4 to ASM5.
     * If we ever go back (via CompilationConfig.ASM_API_VERSION), we need to
     * duplicate the work from the other overloaded version of this method.
     */
    assert CompilationConfig.ASM_API_VERSION == Opcodes.ASM4;
    throw new RuntimeException("this method is deprecated");
  }

  @Override
  public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) {
    // this version of visitMethodInsn() came after ASM4
    assert CompilationConfig.ASM_API_VERSION != Opcodes.ASM4;

    final int argCount = Type.getArgumentTypes(desc).length;
    if (opcode != Opcodes.INVOKESTATIC) {
      final ReplacingBasicValue thisRef = peekFromTop(argCount);

      if (thisRef != null) {
        /*
         * If the this reference is a holder, we need to initialize the variables
         * that replaced it; that amounts to replacing its constructor call with
         * variable initializations.
         */
        if (name.equals("<init>")) {
          oldToNew.get(thisRef.getIndex()).init(adder);
          return;
        } else {
          /*
           * This is disallowed because the holder variables are being ignored in
           * favor of the locals we've replaced them with.
           */
          throw new IllegalStateException("You can't call a method on a value holder.");
        }
      }
    }

    /*
     * If we got here, we're not calling a method on a holder.
     *
     * Does the function being called return a holder?
     */
    if (Type.getReturnType(desc) != Type.VOID_TYPE) {
      ReplacingBasicValue functionReturn = getFunctionReturn();
      if (functionReturn != null) {
        /*
         * The return of this method is an actual instance of the object we're escaping.
         * Update so that it gets mapped correctly.
         */
        super.visitMethodInsn(opcode, owner, name, desc, itf);
        functionReturn.markFunctionReturn();
        return;
      }
    }

    /*
     * Holders can't be passed as arguments to methods, because their contents aren't
     * maintained; we use the locals instead. Therefore, complain if any arguments are holders.
     */
    for (int argDepth = argCount - 1; argDepth >= 0; --argDepth) {
      ReplacingBasicValue argValue = peekFromTop(argDepth);
      if (argValue != null) {
        throw new IllegalStateException(
            String.format("Holder types are not allowed to be passed between methods. " +
                "Ran across problem attempting to invoke method '%s' on line number %d",
                name, lastLineNumber));
      }
    }

    // if we get here, emit this function call as it was
    super.visitMethodInsn(opcode, owner, name, desc, itf);
  }

  @Override
  public void visitEnd() {
    if (logger.isTraceEnabled()) {
      final StringBuilder sb = new StringBuilder();
      sb.append("InstructionModifier ");
      sb.append(name);
      sb.append(' ');
      sb.append(signature);
      sb.append('\n');
      if ((desc != null) && !desc.isEmpty()) {
        sb.append("  desc: ");
        sb.append(desc);
        sb.append('\n');
      }

      int idenId = 0; // used to generate unique ids for the ValueHolderIden's
      int itemCount = 0; // counts up the number of items found
      final HashMap<ValueHolderIden, Integer> seenIdens = new HashMap<>(); // iden -> idenId
      sb.append(" .oldToNew:\n");
      for (final IntObjectCursor<ValueHolderIden.ValueHolderSub> ioc : oldToNew) {
        final ValueHolderIden iden = ioc.value.iden();
        if (!seenIdens.containsKey(iden)) {
          seenIdens.put(iden, ++idenId);
          sb.append("ValueHolderIden[" + idenId + "]:\n");
          iden.dump(sb);
        }

        sb.append("  " + ioc.key + " => " + ioc.value + '[' + seenIdens.get(iden) + "]\n");
        ++itemCount;
      }

      sb.append(" .oldLocalToFirst:\n");
      for (final IntIntCursor iic : oldLocalToFirst) {
        sb.append("  " + iic.key + " => " + iic.value + '\n');
        ++itemCount;
      }

      if (itemCount > 0) {
        logger.debug(sb.toString());
      }
    }

    super.visitEnd();
  }
}
