/*
 * 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.aries.proxy.impl.common;

import static java.lang.String.format;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.DISPATCHER_FIELD;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.DISPATCHER_TYPE;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.LISTENER_FIELD;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.LISTENER_TYPE;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.METHOD_TYPE;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.NO_ARGS;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.OBJECT_TYPE;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.THROWABLE_INAME;
import static org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.WOVEN_PROXY_IFACE_TYPE;
import static org.objectweb.asm.Opcodes.*;

import java.util.Arrays;

import org.apache.aries.proxy.InvocationListener;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;

/**
 * This class weaves dispatch and listener code into a method, there are two known
 * subclasses {@link WovenProxyConcreteMethodAdapter} is used for weaving instance methods
 * {@link WovenProxyAbstractMethodAdapter} is used to provide a delegating
 * implementation of an interface method.
 * 
 * Roughly (but not exactly because it's easier to write working bytecode
 * if you don't have to exactly recreate the Java!) this is trying to 
 * do the following: <code>
 * 
 *      
    if(dispatcher != null) {
      int returnValue;
      Object token = null;
      boolean inInvoke = false;
      try {
        Object toInvoke = dispatcher.call();
        if(listener != null)
          token = listener.preInvoke(toInvoke, method, args);
        
        inInvoke = true;
        returnValue = ((Template) toInvoke).doStuff(args);
        inInvoke = false;
        
        if(listener != null)
          listener.postInvoke(token, toInvoke, method, args);
        
      } catch (Throwable e){
        // whether the the exception is an error is an application decision
        // if we catch an exception we decide carefully which one to
        // throw onwards
        Throwable exceptionToRethrow = null;
        // if the exception came from a precall or postcall 
        // we will rethrow it
        if (!inInvoke) {
          exceptionToRethrow = e;
        }
        // if the exception didn't come from precall or postcall then it
        // came from invoke
        // we will rethrow this exception if it is not a runtime
        // exception, but we must unwrap InvocationTargetExceptions
        else {
          if (!(e instanceof RuntimeException)) {
            exceptionToRethrow = e;
          }
        }
        try {
          if(listener != null)
            listener.postInvokeExceptionalReturn(token, method, null, e);
        } catch (Throwable f) {
          // we caught an exception from
          // postInvokeExceptionalReturn
          // if we haven't already chosen an exception to rethrow then
          // we will throw this exception
          if (exceptionToRethrow == null) {
            exceptionToRethrow = f;
          }
        }
        // if we made it this far without choosing an exception we
        // should throw e
        if (exceptionToRethrow == null) {
          exceptionToRethrow = e;
        }
        throw exceptionToRethrow;
      }
    }
    
    //...original method body
      </code>
 *  
 *   
 */
public abstract class AbstractWovenProxyMethodAdapter extends GeneratorAdapter
{
  /** The type of a RuntimeException */
  private static final Type RUNTIME_EX_TYPE = Type.getType(RuntimeException.class);
  private static final Type THROWABLE_TYPE = Type.getType(Throwable.class);
  
  /** The postInvoke method of an {@link InvocationListener} */
  private static final Method POST_INVOKE_METHOD = getAsmMethodFromClass(InvocationListener.class, "postInvoke", Object.class,
      Object.class, java.lang.reflect.Method.class, Object.class);
  /** The postInvokeExceptionalReturn method of an {@link InvocationListener} */
  private static final Method POST_INVOKE_EXCEPTIONAL_METHOD = getAsmMethodFromClass(InvocationListener.class, 
      "postInvokeExceptionalReturn", Object.class, Object.class,
      java.lang.reflect.Method.class, Throwable.class);
  /** The preInvoke method of an {@link InvocationListener} */
  private static final Method PRE_INVOKE_METHOD = getAsmMethodFromClass(InvocationListener.class, "preInvoke", Object.class,
      java.lang.reflect.Method.class, Object[].class);
  
  
  /** The name of the static field that stores our {@link java.lang.reflect.Method} */
  private final String methodStaticFieldName;
  /** The current method */
  protected final Method currentTransformMethod;
  /** The type of <code>this</code> */
  protected final Type typeBeingWoven;
  /** True if this is a void method */
  private final boolean isVoid;

  //ints for local store
  /** The local we use to store the {@link InvocationListener} token */
  private int preInvokeReturnedToken;
  /** The local we use to note whether we are in the original method body or not */
  private int inNormalMethod;
  /** The local we use to store the invocation target to dispatch to */
  private int dispatchTarget;
  /** The local for storing our method's result */
  private int normalResult;

  //the Labels we need for jumping around the pre/post/postexception and current method code
  /** This marks the start of the try/catch around the pre/postInvoke*/
  private final Label beginTry = new Label();
  /** This marks the end of the try/catch around the pre/postInvoke*/
  private final Label endTry = new Label();

  /** The return type of this method */
  private final Type returnType;
  
  private final Type methodDeclaringType;
  
  private final boolean isMethodDeclaringTypeInterface;
  private boolean isDefaultMethod;
  
  /**
   * Construct a new method adapter
   * @param mv - the method visitor to write to
   * @param access - the access modifiers on this method
   * @param name - the name of this method
   * @param desc - the descriptor of this method
   * @param methodStaticFieldName - the name of the static field that will hold
   *                                the {@link java.lang.reflect.Method} representing
   *                                this method.
   * @param currentTransformMethod - the ASM representation of this method
   * @param proxyType - the type being woven that contains this method
   */
  public AbstractWovenProxyMethodAdapter(MethodVisitor mv, int access, String name, String desc,
      String methodStaticFieldName, Method currentTransformMethod, Type typeBeingWoven,
      Type methodDeclaringType, boolean isMethodDeclaringTypeInterface, boolean isDefaultMethod)
  {
    super(ASM9, mv, access, name, desc);
    this.methodStaticFieldName = methodStaticFieldName;
    this.currentTransformMethod = currentTransformMethod;
    returnType = currentTransformMethod.getReturnType();
    isVoid = returnType.getSort() == Type.VOID;
    this.typeBeingWoven = typeBeingWoven;
    this.methodDeclaringType = methodDeclaringType;
    this.isMethodDeclaringTypeInterface = isMethodDeclaringTypeInterface;
    this.isDefaultMethod = isDefaultMethod;
  }

  @Override
  public abstract void visitCode();

  @Override
  public abstract void visitMaxs(int stack, int locals);
  
  /**
   * Write out the bytecode instructions necessary to do the dispatch.
   * We know the dispatcher is non-null, and we need a try/catch around the
   * invocation and listener calls.
   */
  protected final void writeDispatcher() {
    // Setup locals we will use in the dispatch
    setupLocals();
    
    //Write the try catch block
    visitTryCatchBlock(beginTry, endTry, endTry, THROWABLE_INAME);
    mark(beginTry);
    
    //Start dispatching, get the target object and store it
    loadThis();
    getField(typeBeingWoven, DISPATCHER_FIELD, DISPATCHER_TYPE);
    invokeInterface(DISPATCHER_TYPE, new Method("call", OBJECT_TYPE, NO_ARGS));
    storeLocal(dispatchTarget);
    
    //Pre-invoke, invoke, post-invoke, return
    writePreInvoke();
    //Start the real method
    push(true);
    storeLocal(inNormalMethod);
    
    //Dispatch the method and store the result (null for void)
    loadLocal(dispatchTarget);
    checkCast(methodDeclaringType);
    loadArgs();
    if(isMethodDeclaringTypeInterface) {
      invokeInterface(methodDeclaringType, currentTransformMethod);
    } else {
      invokeVirtual(methodDeclaringType, currentTransformMethod);
    }
    if(isVoid) {
      visitInsn(ACONST_NULL);
    }
    storeLocal(normalResult);
    
    // finish the real method and post-invoke
    push(false);
    storeLocal(inNormalMethod);
    writePostInvoke();
    
    //Return, with the return value if necessary
    if(!!!isVoid) {
      loadLocal(normalResult);
    }
    returnValue();
    
    //End of our try, start of our catch
    mark(endTry);
    writeMethodCatchHandler();
  }
  
  /**
   * Setup the normalResult, inNormalMethod, preInvokeReturnedToken and
   * dispatch target locals.
   */
  private final void setupLocals() {
    if (isVoid){
      normalResult = newLocal(OBJECT_TYPE);
    } else{
      normalResult = newLocal(returnType);
    }
    
    preInvokeReturnedToken = newLocal(OBJECT_TYPE);
    visitInsn(ACONST_NULL);
    storeLocal(preInvokeReturnedToken);
    
    inNormalMethod = newLocal(Type.BOOLEAN_TYPE);
    push(false);
    storeLocal(inNormalMethod);
    
    dispatchTarget = newLocal(OBJECT_TYPE);
    visitInsn(ACONST_NULL);
    storeLocal(dispatchTarget);
  }

  /**
   * Begin trying to invoke the listener, if the listener is
   * null the bytecode will branch to the supplied label, other
   * otherwise it will load the listener onto the stack.
   * @param l The label to branch to
   */
  private final void beginListenerInvocation(Label l) {
    //If there's no listener then skip invocation
    loadThis();
    getField(typeBeingWoven, LISTENER_FIELD, LISTENER_TYPE);
    ifNull(l);
    loadThis();
    getField(typeBeingWoven, LISTENER_FIELD, LISTENER_TYPE);
  }

  /**
   * Write out the preInvoke. This copes with the listener being null
   */
  private final void writePreInvoke() {
    //The place to go if the listener is null
    Label nullListener = newLabel();
    beginListenerInvocation(nullListener);

    // The listener is on the stack, we need (target, method, args)
    
    loadLocal(dispatchTarget);
    getStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
    loadArgArray();
    
    //invoke it and store the token returned
    invokeInterface(LISTENER_TYPE, PRE_INVOKE_METHOD);
    storeLocal(preInvokeReturnedToken);
    
    mark(nullListener);
  }
  
  /**
   * Write out the postInvoke. This copes with the listener being null
   */
  private final void writePostInvoke() {
    //The place to go if the listener is null
    Label nullListener = newLabel();
    beginListenerInvocation(nullListener);
    
    // The listener is on the stack, we need (token, target, method, result)
    
    loadLocal(preInvokeReturnedToken);
    loadLocal(dispatchTarget);
    getStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
    loadLocal(normalResult);
    
    //If the result a primitive then we need to box it
    if (!!!isVoid && returnType.getSort() != Type.OBJECT && returnType.getSort() != Type.ARRAY){
      box(returnType);
    }
    
    //invoke the listener
    invokeInterface(LISTENER_TYPE, POST_INVOKE_METHOD);
    
    mark(nullListener);
  }
  
  /**
   * Write the catch handler for our method level catch, this runs the exceptional
   * post-invoke if there is a listener, and throws the correct exception at the
   * end
   */
  private final void writeMethodCatchHandler() {
    
    //Store the original exception
    int originalException = newLocal(THROWABLE_TYPE);
    storeLocal(originalException);
    
    //Start by initialising exceptionToRethrow
    int exceptionToRethrow = newLocal(THROWABLE_TYPE);
    visitInsn(ACONST_NULL);
    storeLocal(exceptionToRethrow);
    
    //We need another try catch around the postInvokeExceptionalReturn, so here 
    //are some labels and the declaration for it
    Label beforeInvoke = newLabel();
    Label afterInvoke = newLabel();
    visitTryCatchBlock(beforeInvoke, afterInvoke, afterInvoke, THROWABLE_INAME);
    
    //If we aren't in normal flow then set exceptionToRethrow = originalException
    loadLocal(inNormalMethod);
    Label inNormalMethodLabel = newLabel();
    // Jump if not zero (false)
    visitJumpInsn(IFNE, inNormalMethodLabel);
    loadLocal(originalException);
    storeLocal(exceptionToRethrow);
    goTo(beforeInvoke);
    
    mark(inNormalMethodLabel);
    //We are in normal method flow so set exceptionToRethrow = originalException
    //if originalException is not a runtime exception
    loadLocal(originalException);
    instanceOf(RUNTIME_EX_TYPE);
    //If false then store original in toThrow, otherwise go to beforeInvoke
    visitJumpInsn(IFNE, beforeInvoke);
    loadLocal(originalException);
    storeLocal(exceptionToRethrow);
    goTo(beforeInvoke);
    //Setup of variables finished, begin try/catch
       
    //Mark the start of our try
    mark(beforeInvoke);
    //Begin invocation of the listener, jump to throw if null
    Label throwSelectedException = newLabel();
    beginListenerInvocation(throwSelectedException);
    
    //We have a listener, so call it (token, target, method, exception)
    loadLocal(preInvokeReturnedToken);
    loadLocal(dispatchTarget);
    getStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
    loadLocal(originalException);
    invokeInterface(LISTENER_TYPE, POST_INVOKE_EXCEPTIONAL_METHOD);
    goTo(throwSelectedException);
    
    mark(afterInvoke);
    //catching another exception replaces the original
    storeLocal(originalException);

    //Throw exceptionToRethrow if it isn't null, or the original if it is
    Label throwException = newLabel();
    mark(throwSelectedException);
    loadLocal(exceptionToRethrow);
    ifNonNull(throwException);
    loadLocal(originalException);
    storeLocal(exceptionToRethrow);
    
    mark(throwException);
    loadLocal(exceptionToRethrow);
    throwException();
  }
  
  /**
   * This method unwraps woven proxy instances for use in the right-hand side
   * of equals methods
   */
  protected final void unwrapEqualsArgument() {
    
    //Create and initialize a local for our work
    int unwrapLocal = newLocal(OBJECT_TYPE);
    visitInsn(ACONST_NULL);
    storeLocal(unwrapLocal);
    
    Label startUnwrap = newLabel();
    mark(startUnwrap);
    //Load arg and check if it is a WovenProxy instances
    loadArg(0);
    instanceOf(WOVEN_PROXY_IFACE_TYPE);
    Label unwrapFinished = newLabel();
    //Jump if zero (false)
    visitJumpInsn(Opcodes.IFEQ, unwrapFinished);
    //Arg is a wovenProxy, if it is the same as last time then we're done
    loadLocal(unwrapLocal);
    loadArg(0);
    ifCmp(OBJECT_TYPE, EQ, unwrapFinished);
    //Not the same, store current arg in unwrapLocal for next loop
    loadArg(0);
    storeLocal(unwrapLocal);
    
    //So arg is a WovenProxy, but not the same as last time, cast it and store 
    //the result of unwrap.call in the arg
    loadArg(0);
    checkCast(WOVEN_PROXY_IFACE_TYPE);
    //Now unwrap
    invokeInterface(WOVEN_PROXY_IFACE_TYPE, new Method("org_apache_aries_proxy_weaving_WovenProxy_unwrap",
        DISPATCHER_TYPE, NO_ARGS));
    
    //Now we may have a Callable to invoke
    int callable = newLocal(DISPATCHER_TYPE);
    storeLocal(callable);
    loadLocal(callable);
    ifNull(unwrapFinished);
    loadLocal(callable);
    invokeInterface(DISPATCHER_TYPE, new Method("call",
        OBJECT_TYPE, NO_ARGS));
    //Store the result and we're done (for this iteration)
    storeArg(0);
    goTo(startUnwrap);
    
    mark(unwrapFinished);
  }

  /**
   * A utility method for getting an ASM method from a Class
   * @param clazz the class to search
   * @param name The method name
   * @param argTypes The method args
   * @return
   */
  private static final Method getAsmMethodFromClass(Class<?> clazz, String name, Class<?>... argTypes)
  {
    //get the java.lang.reflect.Method to get the types
    java.lang.reflect.Method ilMethod = null;
    try {
      ilMethod = clazz.getMethod(name, argTypes);
    } catch (Exception e) {
      //Should be impossible!
      throw new RuntimeException(format("Error finding InvocationListener method %s with argument types %s.", 
                                        name, Arrays.toString(argTypes)), e);
    }
    //get the ASM method
    return new Method(name, Type.getReturnType(ilMethod), Type.getArgumentTypes(ilMethod));
  }
}
