/***
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000-2007 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.google.gwt.dev.asm.commons;

import com.google.gwt.dev.asm.Label;
import com.google.gwt.dev.asm.MethodVisitor;
import com.google.gwt.dev.asm.Opcodes;
import com.google.gwt.dev.asm.Type;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A {@link com.google.gwt.dev.asm.MethodAdapter} to insert before, after and around
 * advices in methods and constructors. <p> The behavior for constructors is
 * like this: <ol>
 *
 * <li>as long as the INVOKESPECIAL for the object initialization has not been
 * reached, every bytecode instruction is dispatched in the ctor code visitor</li>
 *
 * <li>when this one is reached, it is only added in the ctor code visitor and
 * a JP invoke is added</li>
 *
 * <li>after that, only the other code visitor receives the instructions</li>
 *
 * </ol>
 *
 * @author Eugene Kuleshov
 * @author Eric Bruneton
 */
public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
{
    private static final Object THIS = new Object();
    private static final Object OTHER = new Object();

    protected int methodAccess;
    protected String methodDesc;

    private boolean constructor;
    private boolean superInitialized;
    private List stackFrame;
    private Map branches;

    /**
     * Creates a new {@link AdviceAdapter}.
     *
     * @param mv the method visitor to which this adapter delegates calls.
     * @param access the method's access flags (see {@link Opcodes}).
     * @param name the method's name.
     * @param desc the method's descriptor (see {@link Type Type}).
     */
    protected AdviceAdapter(
        final MethodVisitor mv,
        final int access,
        final String name,
        final String desc)
    {
        super(mv, access, name, desc);
        methodAccess = access;
        methodDesc = desc;

        constructor = "<init>".equals(name);
    }

    public void visitCode() {
        mv.visitCode();
        if (constructor) {
            stackFrame = new ArrayList();
            branches = new HashMap();
        } else {
            superInitialized = true;
            onMethodEnter();
        }
    }

    public void visitLabel(final Label label) {
        mv.visitLabel(label);

        if (constructor && branches != null) {
            List frame = (List) branches.get(label);
            if (frame != null) {
                stackFrame = frame;
                branches.remove(label);
            }
        }
    }

    public void visitInsn(final int opcode) {
        if (constructor) {
            int s;
            switch (opcode) {
                case RETURN: // empty stack
                    onMethodExit(opcode);
                    break;

                case IRETURN: // 1 before n/a after
                case FRETURN: // 1 before n/a after
                case ARETURN: // 1 before n/a after
                case ATHROW: // 1 before n/a after
                    popValue();
                    onMethodExit(opcode);
                    break;

                case LRETURN: // 2 before n/a after
                case DRETURN: // 2 before n/a after
                    popValue();
                    popValue();
                    onMethodExit(opcode);
                    break;

                case NOP:
                case LALOAD: // remove 2 add 2
                case DALOAD: // remove 2 add 2
                case LNEG:
                case DNEG:
                case FNEG:
                case INEG:
                case L2D:
                case D2L:
                case F2I:
                case I2B:
                case I2C:
                case I2S:
                case I2F:
                case ARRAYLENGTH:
                    break;

                case ACONST_NULL:
                case ICONST_M1:
                case ICONST_0:
                case ICONST_1:
                case ICONST_2:
                case ICONST_3:
                case ICONST_4:
                case ICONST_5:
                case FCONST_0:
                case FCONST_1:
                case FCONST_2:
                case F2L: // 1 before 2 after
                case F2D:
                case I2L:
                case I2D:
                    pushValue(OTHER);
                    break;

                case LCONST_0:
                case LCONST_1:
                case DCONST_0:
                case DCONST_1:
                    pushValue(OTHER);
                    pushValue(OTHER);
                    break;

                case IALOAD: // remove 2 add 1
                case FALOAD: // remove 2 add 1
                case AALOAD: // remove 2 add 1
                case BALOAD: // remove 2 add 1
                case CALOAD: // remove 2 add 1
                case SALOAD: // remove 2 add 1
                case POP:
                case IADD:
                case FADD:
                case ISUB:
                case LSHL: // 3 before 2 after
                case LSHR: // 3 before 2 after
                case LUSHR: // 3 before 2 after
                case L2I: // 2 before 1 after
                case L2F: // 2 before 1 after
                case D2I: // 2 before 1 after
                case D2F: // 2 before 1 after
                case FSUB:
                case FMUL:
                case FDIV:
                case FREM:
                case FCMPL: // 2 before 1 after
                case FCMPG: // 2 before 1 after
                case IMUL:
                case IDIV:
                case IREM:
                case ISHL:
                case ISHR:
                case IUSHR:
                case IAND:
                case IOR:
                case IXOR:
                case MONITORENTER:
                case MONITOREXIT:
                    popValue();
                    break;

                case POP2:
                case LSUB:
                case LMUL:
                case LDIV:
                case LREM:
                case LADD:
                case LAND:
                case LOR:
                case LXOR:
                case DADD:
                case DMUL:
                case DSUB:
                case DDIV:
                case DREM:
                    popValue();
                    popValue();
                    break;

                case IASTORE:
                case FASTORE:
                case AASTORE:
                case BASTORE:
                case CASTORE:
                case SASTORE:
                case LCMP: // 4 before 1 after
                case DCMPL:
                case DCMPG:
                    popValue();
                    popValue();
                    popValue();
                    break;

                case LASTORE:
                case DASTORE:
                    popValue();
                    popValue();
                    popValue();
                    popValue();
                    break;

                case DUP:
                    pushValue(peekValue());
                    break;

                case DUP_X1:
                    s = stackFrame.size();
                    stackFrame.add(s - 2, stackFrame.get(s - 1));
                    break;

                case DUP_X2:
                    s = stackFrame.size();
                    stackFrame.add(s - 3, stackFrame.get(s - 1));
                    break;

                case DUP2:
                    s = stackFrame.size();
                    stackFrame.add(s - 2, stackFrame.get(s - 1));
                    stackFrame.add(s - 2, stackFrame.get(s - 1));
                    break;

                case DUP2_X1:
                    s = stackFrame.size();
                    stackFrame.add(s - 3, stackFrame.get(s - 1));
                    stackFrame.add(s - 3, stackFrame.get(s - 1));
                    break;

                case DUP2_X2:
                    s = stackFrame.size();
                    stackFrame.add(s - 4, stackFrame.get(s - 1));
                    stackFrame.add(s - 4, stackFrame.get(s - 1));
                    break;

                case SWAP:
                    s = stackFrame.size();
                    stackFrame.add(s - 2, stackFrame.get(s - 1));
                    stackFrame.remove(s);
                    break;
            }
        } else {
            switch (opcode) {
                case RETURN:
                case IRETURN:
                case FRETURN:
                case ARETURN:
                case LRETURN:
                case DRETURN:
                case ATHROW:
                    onMethodExit(opcode);
                    break;
            }
        }
        mv.visitInsn(opcode);
    }

    public void visitVarInsn(final int opcode, final int var) {
        super.visitVarInsn(opcode, var);

        if (constructor) {
            switch (opcode) {
                case ILOAD:
                case FLOAD:
                    pushValue(OTHER);
                    break;
                case LLOAD:
                case DLOAD:
                    pushValue(OTHER);
                    pushValue(OTHER);
                    break;
                case ALOAD:
                    pushValue(var == 0 ? THIS : OTHER);
                    break;
                case ASTORE:
                case ISTORE:
                case FSTORE:
                    popValue();
                    break;
                case LSTORE:
                case DSTORE:
                    popValue();
                    popValue();
                    break;
            }
        }
    }

    public void visitFieldInsn(
        final int opcode,
        final String owner,
        final String name,
        final String desc)
    {
        mv.visitFieldInsn(opcode, owner, name, desc);

        if (constructor) {
            char c = desc.charAt(0);
            boolean longOrDouble = c == 'J' || c == 'D';
            switch (opcode) {
                case GETSTATIC:
                    pushValue(OTHER);
                    if (longOrDouble) {
                        pushValue(OTHER);
                    }
                    break;
                case PUTSTATIC:
                    popValue();
                    if (longOrDouble) {
                        popValue();
                    }
                    break;
                case PUTFIELD:
                    popValue();
                    if (longOrDouble) {
                        popValue();
                        popValue();
                    }
                    break;
                // case GETFIELD:
                default:
                    if (longOrDouble) {
                        pushValue(OTHER);
                    }
            }
        }
    }

    public void visitIntInsn(final int opcode, final int operand) {
        mv.visitIntInsn(opcode, operand);

        if (constructor && opcode!=NEWARRAY) {
            pushValue(OTHER);
        }
    }

    public void visitLdcInsn(final Object cst) {
        mv.visitLdcInsn(cst);

        if (constructor) {
            pushValue(OTHER);
            if (cst instanceof Double || cst instanceof Long) {
                pushValue(OTHER);
            }
        }
    }

    public void visitMultiANewArrayInsn(final String desc, final int dims) {
        mv.visitMultiANewArrayInsn(desc, dims);

        if (constructor) {
            for (int i = 0; i < dims; i++) {
                popValue();
            }
            pushValue(OTHER);
        }
    }

    public void visitTypeInsn(final int opcode, final String type) {
        mv.visitTypeInsn(opcode, type);

        // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack
        if (constructor && opcode == NEW) {
            pushValue(OTHER);
        }
    }

    public void visitMethodInsn(
        final int opcode,
        final String owner,
        final String name,
        final String desc)
    {
        mv.visitMethodInsn(opcode, owner, name, desc);

        if (constructor) {
            Type[] types = Type.getArgumentTypes(desc);
            for (int i = 0; i < types.length; i++) {
                popValue();
                if (types[i].getSize() == 2) {
                    popValue();
                }
            }
            switch (opcode) {
                // case INVOKESTATIC:
                // break;

                case INVOKEINTERFACE:
                case INVOKEVIRTUAL:
                    popValue(); // objectref
                    break;

                case INVOKESPECIAL:
                    Object type = popValue(); // objectref
                    if (type == THIS && !superInitialized) {
                        onMethodEnter();
                        superInitialized = true;
                        // once super has been initialized it is no longer
                        // necessary to keep track of stack state
                        constructor = false;
                    }
                    break;
            }

            Type returnType = Type.getReturnType(desc);
            if (returnType != Type.VOID_TYPE) {
                pushValue(OTHER);
                if (returnType.getSize() == 2) {
                    pushValue(OTHER);
                }
            }
        }
    }

    public void visitJumpInsn(final int opcode, final Label label) {
        mv.visitJumpInsn(opcode, label);

        if (constructor) {
            switch (opcode) {
                case IFEQ:
                case IFNE:
                case IFLT:
                case IFGE:
                case IFGT:
                case IFLE:
                case IFNULL:
                case IFNONNULL:
                    popValue();
                    break;

                case IF_ICMPEQ:
                case IF_ICMPNE:
                case IF_ICMPLT:
                case IF_ICMPGE:
                case IF_ICMPGT:
                case IF_ICMPLE:
                case IF_ACMPEQ:
                case IF_ACMPNE:
                    popValue();
                    popValue();
                    break;

                case JSR:
                    pushValue(OTHER);
                    break;
            }
            addBranch(label);
        }
    }

    public void visitLookupSwitchInsn(
        final Label dflt,
        final int[] keys,
        final Label[] labels)
    {
        mv.visitLookupSwitchInsn(dflt, keys, labels);

        if (constructor) {
            popValue();
            addBranches(dflt, labels);
        }
    }

    public void visitTableSwitchInsn(
        final int min,
        final int max,
        final Label dflt,
        final Label[] labels)
    {
        mv.visitTableSwitchInsn(min, max, dflt, labels);

        if (constructor) {
            popValue();
            addBranches(dflt, labels);
        }
    }

    private void addBranches(final Label dflt, final Label[] labels) {
        addBranch(dflt);
        for (int i = 0; i < labels.length; i++) {
            addBranch(labels[i]);
        }
    }

    private void addBranch(final Label label) {
        if (branches.containsKey(label)) {
            return;
        }
        branches.put(label, new ArrayList(stackFrame));
    }

    private Object popValue() {
        return stackFrame.remove(stackFrame.size() - 1);
    }

    private Object peekValue() {
        return stackFrame.get(stackFrame.size() - 1);
    }

    private void pushValue(final Object o) {
        stackFrame.add(o);
    }

    /**
     * Called at the beginning of the method or after super class class call in
     * the constructor. <br><br>
     *
     * <i>Custom code can use or change all the local variables, but should not
     * change state of the stack.</i>
     */
    protected void onMethodEnter() {
    }

    /**
     * Called before explicit exit from the method using either return or throw.
     * Top element on the stack contains the return value or exception instance.
     * For example:
     *
     * <pre>
     *   public void onMethodExit(int opcode) {
     *     if(opcode==RETURN) {
     *         visitInsn(ACONST_NULL);
     *     } else if(opcode==ARETURN || opcode==ATHROW) {
     *         dup();
     *     } else {
     *         if(opcode==LRETURN || opcode==DRETURN) {
     *             dup2();
     *         } else {
     *             dup();
     *         }
     *         box(Type.getReturnType(this.methodDesc));
     *     }
     *     visitIntInsn(SIPUSH, opcode);
     *     visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
     *   }
     *
     *   // an actual call back method
     *   public static void onExit(int opcode, Object param) {
     *     ...
     * </pre>
     *
     * <br><br>
     *
     * <i>Custom code can use or change all the local variables, but should not
     * change state of the stack.</i>
     *
     * @param opcode one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN,
     *        DRETURN or ATHROW
     *
     */
    protected void onMethodExit(int opcode) {
    }

    // TODO onException, onMethodCall

}
