/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.internal.lookup;

import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptRuntime;

/**
 * MethodHandle Lookup management for Nashorn.
 */
public final class Lookup {

    /**
     * A global singleton that points to the {@link MethodHandleFunctionality}. This is basically
     * a collection of wrappers to the standard methods in {@link MethodHandle}, {@link MethodHandles} and
     * {@link java.lang.invoke.MethodHandles.Lookup}, but instrumentation and debugging purposes we need
     * intercept points.
     * <p>
     * All method handle operations in Nashorn should go through this field, not directly to the classes
     * in {@code java.lang.invoke}
     */
    public static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();

    /** Method handle to the empty getter */
    public static final MethodHandle EMPTY_GETTER = findOwnMH("emptyGetter", Object.class, Object.class);

    /** Method handle to the empty setter */
    public static final MethodHandle EMPTY_SETTER = findOwnMH("emptySetter", void.class, Object.class, Object.class);

    /** Method handle to a getter that only throws type error */
    public static final MethodHandle TYPE_ERROR_THROWER_GETTER = findOwnMH("typeErrorThrowerGetter", Object.class, Object.class);

    /** Method handle to a setter that only throws type error */
    public static final MethodHandle TYPE_ERROR_THROWER_SETTER = findOwnMH("typeErrorThrowerSetter", void.class, Object.class, Object.class);

    /** Method handle to the most generic of getters, the one that returns an Object */
    public static final MethodType GET_OBJECT_TYPE = MH.type(Object.class, Object.class);

    /** Method handle to the most generic of setters, the one that takes an Object */
    public static final MethodType SET_OBJECT_TYPE = MH.type(void.class, Object.class, Object.class);

    /** Method handle to the primitive getters, the one that returns an long/int/double */
    public static final MethodType GET_PRIMITIVE_TYPE = MH.type(long.class, Object.class);

    /** Method handle to the primitive getters, the one that returns an long/int/double */
    public static final MethodType SET_PRIMITIVE_TYPE = MH.type(void.class, Object.class, long.class);

    private Lookup() {
    }

    /**
     * Empty getter implementation. Nop
     * @param self self reference
     * @return undefined
     */
    public static Object emptyGetter(final Object self) {
        return UNDEFINED;
    }

    /**
     * Empty setter implementation. Nop
     * @param self  self reference
     * @param value value (ignored)
     */
    public static void emptySetter(final Object self, final Object value) {
        // do nothing!!
    }

    /**
     * Return a method handle to the empty getter, with a different
     * return type value. It will still be undefined cast to whatever
     * return value property was specified
     *
     * @param type return value type
     *
     * @return undefined as return value type
     */
    public static MethodHandle emptyGetter(final Class<?> type) {
        return filterReturnType(EMPTY_GETTER, type);
    }

    /**
     * Getter function that always throws type error
     *
     * @param self  self reference
     * @return undefined (but throws error before return point)
     */
    public static Object typeErrorThrowerGetter(final Object self) {
        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
    }

    /**
     * Getter function that always throws type error
     *
     * @param self  self reference
     * @param value (ignored)
     */
    public static void typeErrorThrowerSetter(final Object self, final Object value) {
        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
    }

    /**
     * This method filters primitive argument types using JavaScript semantics. For example,
     * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
     * If you are returning values to JavaScript that have to be of a specific type, this is
     * the correct return value filter to use, as the explicitCastArguments just uses the
     * Java boxing equivalents
     *
     * @param mh   method handle for which to filter argument value
     * @param n    argument index
     * @param from old argument type, the new one is given by the sent method handle
     * @return method handle for appropriate argument type conversion
     */
    public static MethodHandle filterArgumentType(final MethodHandle mh, final int n, final Class<?> from) {
        final Class<?> to = mh.type().parameterType(n);

        if (from == int.class) {
            //fallthru
        } else if (from == long.class) {
            if (to == int.class) {
                return MH.filterArguments(mh, n, JSType.TO_INT32_L.methodHandle());
            }
            //fallthru
        } else if (from == double.class) {
            if (to == int.class) {
                return MH.filterArguments(mh, n, JSType.TO_INT32_D.methodHandle());
            } else if (to == long.class) {
                return MH.filterArguments(mh, n, JSType.TO_UINT32_D.methodHandle());
            }
            //fallthru
        } else if (!from.isPrimitive()) {
            if (to == int.class) {
                return MH.filterArguments(mh, n, JSType.TO_INT32.methodHandle());
            } else if (to == long.class) {
                return MH.filterArguments(mh, n, JSType.TO_UINT32.methodHandle());
            } else if (to == double.class) {
                return MH.filterArguments(mh, n, JSType.TO_NUMBER.methodHandle());
            } else if (!to.isPrimitive()) {
                return mh;
            }

            assert false : "unsupported Lookup.filterReturnType type " + from + " -> " + to;
        }

        //use a standard cast - we don't need to check JavaScript special cases
        return MH.explicitCastArguments(mh, mh.type().changeParameterType(n, from));
    }

    /**
     * This method filters primitive return types using JavaScript semantics. For example,
     * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
     * If you are returning values to JavaScript that have to be of a specific type, this is
     * the correct return value filter to use, as the explicitCastArguments just uses the
     * Java boxing equivalents
     *
     * @param mh   method handle for which to filter return value
     * @param type new return type
     * @return method handle for appropriate return type conversion
     */
    public static MethodHandle filterReturnType(final MethodHandle mh, final Class<?> type) {
        final Class<?> retType = mh.type().returnType();

        if (retType == int.class) {
            //fallthru
        } else if (retType == long.class) {
            if (type == int.class) {
                return MH.filterReturnValue(mh, JSType.TO_INT32_L.methodHandle());
            }
            //fallthru
        } else if (retType == double.class) {
            if (type == int.class) {
                return MH.filterReturnValue(mh, JSType.TO_INT32_D.methodHandle());
            } else if (type == long.class) {
                return MH.filterReturnValue(mh, JSType.TO_UINT32_D.methodHandle());
            }
            //fallthru
        } else if (!retType.isPrimitive()) {
            if (type == int.class) {
                return MH.filterReturnValue(mh, JSType.TO_INT32.methodHandle());
            } else if (type == long.class) {
                return MH.filterReturnValue(mh, JSType.TO_UINT32.methodHandle());
            } else if (type == double.class) {
                return MH.filterReturnValue(mh, JSType.TO_NUMBER.methodHandle());
            } else if (!type.isPrimitive()) {
                return mh;
            }

            assert false : "unsupported Lookup.filterReturnType type " + retType + " -> " + type;
        }

        //use a standard cast - we don't need to check JavaScript special cases
        return MH.explicitCastArguments(mh, mh.type().changeReturnType(type));
    }

    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
        return MH.findStatic(MethodHandles.lookup(), Lookup.class, name, MH.type(rtype, types));
    }

}
