/*
 * 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.tools.nasgen;

import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.STRING_DESC;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ScriptObject;

/**
 * Details about a Java method or field annotated with any of the field/method
 * annotations from the jdk.nashorn.internal.objects.annotations package.
 */
public final class MemberInfo implements Cloneable {
    // class loader of this class
    private static ClassLoader myLoader = MemberInfo.class.getClassLoader();

    /**
     * The different kinds of available class annotations
     */
    public static enum Kind {

        /**
         * This is a script class
         */
        SCRIPT_CLASS,
        /**
         * This is a constructor
         */
        CONSTRUCTOR,
        /**
         * This is a function
         */
        FUNCTION,
        /**
         * This is a getter
         */
        GETTER,
        /**
         * This is a setter
         */
        SETTER,
        /**
         * This is a property
         */
        PROPERTY,
        /**
         * This is a specialized version of a function
         */
        SPECIALIZED_FUNCTION,
    }

    // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute
    static final int DEFAULT_ATTRIBUTES = 0x0;

    static final int DEFAULT_ARITY = -2;

    // the kind of the script annotation - one of the above constants
    private MemberInfo.Kind kind;
    // script property name
    private String name;
    // script property attributes
    private int attributes;
    // name of the java member
    private String javaName;
    // type descriptor of the java member
    private String javaDesc;
    // access bits of the Java field or method
    private int javaAccess;
    // initial value for static @Property fields
    private Object value;
    // class whose object is created to fill property value
    private String initClass;
    // arity of the Function or Constructor
    private int arity;

    private Where where;

    private Type linkLogicClass;

    private boolean isSpecializedConstructor;

    private boolean isOptimistic;

    /**
     * @return the kind
     */
    public Kind getKind() {
        return kind;
    }

    /**
     * @param kind the kind to set
     */
    public void setKind(final Kind kind) {
        this.kind = kind;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Tag something as specialized constructor or not
     * @param isSpecializedConstructor boolean, true if specialized constructor
     */
    public void setIsSpecializedConstructor(final boolean isSpecializedConstructor) {
        this.isSpecializedConstructor = isSpecializedConstructor;
    }

    /**
     * Check if something is a specialized constructor
     * @return true if specialized constructor
     */
    public boolean isSpecializedConstructor() {
        return isSpecializedConstructor;
    }

    /**
     * Check if this is an optimistic builtin function
     * @return true if optimistic builtin
     */
    public boolean isOptimistic() {
        return isOptimistic;
    }

    /**
     * Tag something as optimistic builtin or not
     * @param isOptimistic boolean, true if builtin constructor
     */
    public void setIsOptimistic(final boolean isOptimistic) {
        this.isOptimistic = isOptimistic;
    }

    /**
     * Get the SpecializedFunction guard for specializations, i.e. optimistic
     * builtins
     * @return specialization, null if none
     */
    public Type getLinkLogicClass() {
        return linkLogicClass;
    }

    /**
     * Set the SpecializedFunction link logic class for specializations, i.e. optimistic
     * builtins
     * @param linkLogicClass link logic class
     */

    public void setLinkLogicClass(final Type linkLogicClass) {
        this.linkLogicClass = linkLogicClass;
    }

    /**
     * @return the attributes
     */
    public int getAttributes() {
        return attributes;
    }

    /**
     * @param attributes the attributes to set
     */
    public void setAttributes(final int attributes) {
        this.attributes = attributes;
    }

    /**
     * @return the javaName
     */
    public String getJavaName() {
        return javaName;
    }

    /**
     * @param javaName the javaName to set
     */
    public void setJavaName(final String javaName) {
        this.javaName = javaName;
    }

    /**
     * @return the javaDesc
     */
    public String getJavaDesc() {
        return javaDesc;
    }

    void setJavaDesc(final String javaDesc) {
        this.javaDesc = javaDesc;
    }

    int getJavaAccess() {
        return javaAccess;
    }

    void setJavaAccess(final int access) {
        this.javaAccess = access;
    }

    Object getValue() {
        return value;
    }

    void setValue(final Object value) {
        this.value = value;
    }

    Where getWhere() {
        return where;
    }

    void setWhere(final Where where) {
        this.where = where;
    }

    boolean isFinal() {
        return (javaAccess & Opcodes.ACC_FINAL) != 0;
    }

    boolean isStatic() {
        return (javaAccess & Opcodes.ACC_STATIC) != 0;
    }

    boolean isStaticFinal() {
        return isStatic() && isFinal();
    }

    boolean isInstanceGetter() {
        return kind == Kind.GETTER && where == Where.INSTANCE;
    }

    /**
     * Check whether this MemberInfo is a getter that resides in the instance
     *
     * @return true if instance setter
     */
    boolean isInstanceSetter() {
        return kind == Kind.SETTER && where == Where.INSTANCE;
    }

    boolean isInstanceProperty() {
        return kind == Kind.PROPERTY && where == Where.INSTANCE;
    }

    boolean isInstanceFunction() {
        return kind == Kind.FUNCTION && where == Where.INSTANCE;
    }

    boolean isPrototypeGetter() {
        return kind == Kind.GETTER && where == Where.PROTOTYPE;
    }

    boolean isPrototypeSetter() {
        return kind == Kind.SETTER && where == Where.PROTOTYPE;
    }

    boolean isPrototypeProperty() {
        return kind == Kind.PROPERTY && where == Where.PROTOTYPE;
    }

    boolean isPrototypeFunction() {
        return kind == Kind.FUNCTION && where == Where.PROTOTYPE;
    }

    boolean isConstructorGetter() {
        return kind == Kind.GETTER && where == Where.CONSTRUCTOR;
    }

    boolean isConstructorSetter() {
        return kind == Kind.SETTER && where == Where.CONSTRUCTOR;
    }

    boolean isConstructorProperty() {
        return kind == Kind.PROPERTY && where == Where.CONSTRUCTOR;
    }

    boolean isConstructorFunction() {
        return kind == Kind.FUNCTION && where == Where.CONSTRUCTOR;
    }

    boolean isConstructor() {
        return kind == Kind.CONSTRUCTOR;
    }

    void verify() {
        switch (kind) {
            case CONSTRUCTOR: {
                final Type returnType = Type.getReturnType(javaDesc);
                if (!isJSObjectType(returnType)) {
                    error("return value of a @Constructor method should be of Object type, found " + returnType);
                }
                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
                if (argTypes.length < 2) {
                    error("@Constructor methods should have at least 2 args");
                }
                if (!argTypes[0].equals(Type.BOOLEAN_TYPE)) {
                    error("first argument of a @Constructor method should be of boolean type, found " + argTypes[0]);
                }
                if (!isJavaLangObject(argTypes[1])) {
                    error("second argument of a @Constructor method should be of Object type, found " + argTypes[0]);
                }

                if (argTypes.length > 2) {
                    for (int i = 2; i < argTypes.length - 1; i++) {
                        if (!isJavaLangObject(argTypes[i])) {
                            error(i + "'th argument of a @Constructor method should be of Object type, found " + argTypes[i]);
                        }
                    }

                    final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
                    final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
                    if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
                        error("last argument of a @Constructor method is neither Object nor Object[] type: " + lastArgTypeDesc);
                    }

                    if (isVarArg && argTypes.length > 3) {
                        error("vararg of a @Constructor method has more than 3 arguments");
                    }
                }
            }
            break;
            case FUNCTION: {
                final Type returnType = Type.getReturnType(javaDesc);
                if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) {
                    error("return value of a @Function method should be a valid JS type, found " + returnType);
                }
                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
                if (argTypes.length < 1) {
                    error("@Function methods should have at least 1 arg");
                }
                if (!isJavaLangObject(argTypes[0])) {
                    error("first argument of a @Function method should be of Object type, found " + argTypes[0]);
                }

                if (argTypes.length > 1) {
                    for (int i = 1; i < argTypes.length - 1; i++) {
                        if (!isJavaLangObject(argTypes[i])) {
                            error(i + "'th argument of a @Function method should be of Object type, found " + argTypes[i]);
                        }
                    }

                    final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
                    final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
                    if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
                        error("last argument of a @Function method is neither Object nor Object[] type: " + lastArgTypeDesc);
                    }

                    if (isVarArg && argTypes.length > 2) {
                        error("vararg @Function method has more than 2 arguments");
                    }
                }
            }
            break;
            case SPECIALIZED_FUNCTION: {
                final Type returnType = Type.getReturnType(javaDesc);
                if (!(isValidJSType(returnType) || (isSpecializedConstructor() && Type.VOID_TYPE == returnType))) {
                    error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType);
                }
                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
                for (int i = 0; i < argTypes.length; i++) {
                    if (!isValidJSType(argTypes[i])) {
                        error(i + "'th argument of a @SpecializedFunction method is not valid JS type, found " + argTypes[i]);
                    }
                }
            }
            break;
            case GETTER: {
                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
                if (argTypes.length != 1) {
                    error("@Getter methods should have one argument");
                }
                if (!isJavaLangObject(argTypes[0])) {
                    error("first argument of a @Getter method should be of Object type, found: " + argTypes[0]);
                }

                if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) {
                    error("return type of getter should not be void");
                }
            }
            break;
            case SETTER: {
                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
                if (argTypes.length != 2) {
                    error("@Setter methods should have two arguments");
                }
                if (!isJavaLangObject(argTypes[0])) {
                    error("first argument of a @Setter method should be of Object type, found: " + argTypes[0]);
                }
                if (!Type.getReturnType(javaDesc).toString().equals("V")) {
                    error("return type of of a @Setter method should be void, found: " + Type.getReturnType(javaDesc));
                }
            }
            break;
            case PROPERTY: {
                if (where == Where.CONSTRUCTOR) {
                    if (isStatic()) {
                        if (!isFinal()) {
                            error("static Where.CONSTRUCTOR @Property should be final");
                        }

                        if (!isJSPrimitiveType(Type.getType(javaDesc))) {
                            error("static Where.CONSTRUCTOR @Property should be a JS primitive");
                        }
                    }
                } else if (where == Where.PROTOTYPE) {
                    if (isStatic()) {
                        if (!isFinal()) {
                            error("static Where.PROTOTYPE @Property should be final");
                        }

                        if (!isJSPrimitiveType(Type.getType(javaDesc))) {
                            error("static Where.PROTOTYPE @Property should be a JS primitive");
                        }
                    }
                }
            }
            break;

            default:
            break;
        }
    }

    private static boolean isValidJSType(final Type type) {
        return isJSPrimitiveType(type) || isJSObjectType(type);
    }

    private static boolean isJSPrimitiveType(final Type type) {
        switch (type.getSort()) {
            case Type.BOOLEAN:
            case Type.INT:
            case Type.LONG:
            case Type.DOUBLE:
                return true;
            default:
                return false;
        }
    }

    private static boolean isJSObjectType(final Type type) {
        return isJavaLangObject(type) || isJavaLangString(type) || isScriptObject(type);
    }

    private static boolean isJavaLangObject(final Type type) {
        return type.getDescriptor().equals(OBJECT_DESC);
    }

    private static boolean isJavaLangString(final Type type) {
        return type.getDescriptor().equals(STRING_DESC);
    }

    private static boolean isScriptObject(final Type type) {
        if (type.getDescriptor().equals(SCRIPTOBJECT_DESC)) {
            return true;
        }

        if (type.getSort() == Type.OBJECT) {
            try {
                final Class<?> clazz = Class.forName(type.getClassName(), false, myLoader);
                return ScriptObject.class.isAssignableFrom(clazz);
            } catch (final ClassNotFoundException cnfe) {
                return false;
            }
        }

        return false;
    }

    private void error(final String msg) {
        throw new RuntimeException(javaName + " of type " + javaDesc + " : " + msg);
    }

    /**
     * @return the initClass
     */
    String getInitClass() {
        return initClass;
    }

    /**
     * @param initClass the initClass to set
     */
    void setInitClass(final String initClass) {
        this.initClass = initClass;
    }

    @Override
    protected Object clone() {
        try {
            return super.clone();
        } catch (final CloneNotSupportedException e) {
            assert false : "clone not supported " + e;
            return null;
        }
    }

    /**
     * @return the arity
     */
    int getArity() {
        return arity;
    }

    /**
     * @param arity the arity to set
     */
    void setArity(final int arity) {
        this.arity = arity;
    }
}
