/*
 * Copyright 2003-2013 the original author or authors.
 *
 * 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 org.codehaus.groovy.runtime;

import groovy.lang.GroovyRuntimeException;
import org.codehaus.groovy.vmplugin.VMPlugin;
import org.codehaus.groovy.vmplugin.VMPluginFactory;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This class is a general adapter to map a call to a Java interface
 * to a given delegate.
 *
 * @author Ben Yu
 * @author <a href="mailto:blackdrag@gmx.org">Jochen Theodorou</a>
 */
public abstract class ConversionHandler implements InvocationHandler, Serializable {
    private Object delegate;
    private static final long serialVersionUID = 1162833717190835227L;
    private ConcurrentHashMap handleCache;
    {
        if (VMPluginFactory.getPlugin().getVersion()>=7) handleCache = new ConcurrentHashMap();
    }

    /**
     * Creates a ConversionHandler with an delegate.
     *
     * @param delegate the delegate
     * @throws IllegalArgumentException if the given delegate is null
     */
    public ConversionHandler(Object delegate) {
        if (delegate == null) throw new IllegalArgumentException("delegate must not be null");
        this.delegate = delegate;
    }

    /**
     * Returns the delegate.
     *
     * @return the delegate
     */
    public Object getDelegate() {
        return delegate;
    }

    /**
     * This method is a default implementation for the invoke method given in
     * InvocationHandler. Any call to a method with a declaring class that is
     * not Object, excluding toString() and default methods is redirected to invokeCustom.
     * <p>
     * Methods like equals and hashcode are called on the class itself instead
     * of the delegate because they are considered fundamental methods that should
     * not be overwritten. The toString() method gets special treatment as it is
     * deemed to be a method that you might wish to override when called from Groovy.
     * Interface default methods from Java 8 on the other hand are considered being
     * default implementations you don't normally want to change. So they are called
     * directly too
     * </p><p>
     * In many scenarios, it is better to overwrite the invokeCustom method where
     * the core Object related methods are filtered out.
     *</p>
     * @param proxy  the proxy
     * @param method the method
     * @param args   the arguments
     * @return the result of the invocation by method or delegate
     * @throws Throwable if caused by the delegate or the method
     * @see #invokeCustom(Object, Method, Object[])
     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        VMPlugin plugin = VMPluginFactory.getPlugin();
        if (plugin.getVersion()>=7 && isDefaultMethod(method)) {
            Object handle = handleCache.get(method);
            if (handle == null) {
                handle = plugin.getInvokeSpecialHandle(method, proxy);
                handleCache.putIfAbsent(method, handle);
            }
            return plugin.invokeHandle(handle, args);
        }

        if (!checkMethod(method)) {
            try {
                return invokeCustom(proxy, method, args);
            } catch (GroovyRuntimeException gre) {
                throw ScriptBytecodeAdapter.unwrap(gre);
            }
        }

        try {
            return method.invoke(this, args);
        } catch (InvocationTargetException ite) {
            throw ite.getTargetException();
        }
    }

    protected boolean isDefaultMethod(Method method) {
        return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
                Modifier.PUBLIC) && method.getDeclaringClass().isInterface();
    }

    protected boolean checkMethod(Method method) {
        return isCoreObjectMethod(method);
    }

    /**
     * This method is called for all Methods not defined on Object.
     * The delegate should be called here.
     *
     * @param proxy  the proxy
     * @param method the method
     * @param args   the arguments
     * @return the result of the invocation of the delegate
     * @throws Throwable any exception causes by the delegate
     * @see #invoke(Object, Method, Object[])
     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
     */
    public abstract Object invokeCustom(Object proxy, Method method, Object[] args) throws Throwable;

    /**
     * Indicates whether some other object is "equal to" this one.
     * The delegate is used if the class of the parameter and the
     * current class are equal. In other cases the method will return
     * false. The exact class is here used, if inheritance is needed,
     * this method must be overwritten.
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        if (obj instanceof Proxy) {
            obj = Proxy.getInvocationHandler(obj);
        }

        if (obj instanceof ConversionHandler) {
            return (((ConversionHandler) obj).getDelegate()).equals(delegate);
        } else {
            return false;
        }
    }

    /**
     * Returns a hash code value for the delegate.
     *
     * @see java.lang.Object#hashCode()
     */
    public int hashCode() {
        return delegate.hashCode();
    }

    /**
     * Returns a String version of the delegate.
     *
     * @see java.lang.Object#toString()
     */
    public String toString() {
        return delegate.toString();
    }

    /**
     * Checks whether a method is a core method from java.lang.Object.
     * Such methods often receive special treatment because they are
     * deemed fundamental enough to not be tampered with.
     *
     * @param method the method to check
     * @return true if the method is deemed to be a core method
     */
    public static boolean isCoreObjectMethod(Method method) {
        return Object.class.equals(method.getDeclaringClass());
    }

}
