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

import static jdk.nashorn.internal.lookup.Lookup.MH;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.Source;

/**
 * This class represents constant names of variables, methods and fields in
 * the compiler
 */

public enum CompilerConstants {
    /** the __FILE__ variable */
    __FILE__,

    /** the __DIR__ variable */
    __DIR__,

    /** the __LINE__ variable */
    __LINE__,

    /** constructor name */
    INIT("<init>"),

    /** static initializer name */
    CLINIT("<clinit>"),

    /** eval name */
    EVAL("eval"),

    /** source name and class */
    SOURCE("source", Source.class),

    /** constants name and class */
    CONSTANTS("constants", Object[].class),

    /** strict mode field name and type */
    STRICT_MODE("strictMode", boolean.class),

    /** default script name */
    DEFAULT_SCRIPT_NAME("Script"),

    /** function prefix for anonymous functions */
    ANON_FUNCTION_PREFIX("L:"),

    /** method name for Java method that is the program entry point */
    PROGRAM(":program"),

    /** method name for Java method that creates the script function for the program */
    CREATE_PROGRAM_FUNCTION(":createProgramFunction"),

    /**
     * "this" name symbol for a parameter representing ECMAScript "this" in static methods that are compiled
     * representations of ECMAScript functions. It is not assigned a slot, as its position in the method signature is
     * dependent on other factors (most notably, callee can precede it).
     */
    THIS("this", Object.class),

    /** this debugger symbol */
    THIS_DEBUGGER(":this"),

    /** scope name, type and slot */
    SCOPE(":scope", ScriptObject.class, 2),

    /** the return value variable name were intermediate results are stored for scripts */
    RETURN(":return"),

    /** the callee value variable when necessary */
    CALLEE(":callee", ScriptFunction.class),

    /** the varargs variable when necessary */
    VARARGS(":varargs", Object[].class),

    /** the arguments variable (visible to function body). Initially set to ARGUMENTS, but can be reassigned by code in
     * the function body.*/
    ARGUMENTS_VAR("arguments", Object.class),

    /** the internal arguments object, when necessary (not visible to scripts, can't be reassigned). */
    ARGUMENTS(":arguments", ScriptObject.class),

    /** prefix for apply-to-call exploded arguments */
    EXPLODED_ARGUMENT_PREFIX(":xarg"),

    /** prefix for iterators for for (x in ...) */
    ITERATOR_PREFIX(":i", Iterator.class),

    /** prefix for tag variable used for switch evaluation */
    SWITCH_TAG_PREFIX(":s"),

    /** prefix for JVM exceptions */
    EXCEPTION_PREFIX(":e", Throwable.class),

    /** prefix for quick slots generated in Store */
    QUICK_PREFIX(":q"),

    /** prefix for temporary variables */
    TEMP_PREFIX(":t"),

    /** prefix for literals */
    LITERAL_PREFIX(":l"),

    /** prefix for regexps */
    REGEX_PREFIX(":r"),

    /** "this" used in non-static Java methods; always in slot 0 */
    JAVA_THIS(null, 0),

    /** Map parameter in scope object constructors; always in slot 1 */
    INIT_MAP(null, 1),

    /** Parent scope parameter in scope object constructors; always in slot 2 */
    INIT_SCOPE(null, 2),

    /** Arguments parameter in scope object constructors; in slot 3 when present */
    INIT_ARGUMENTS(null, 3),

    /** prefix for all ScriptObject subclasses with dual object/primitive fields, see {@link ObjectClassGenerator} */
    JS_OBJECT_DUAL_FIELD_PREFIX("JD"),

    /** prefix for all ScriptObject subclasses with object fields only, see {@link ObjectClassGenerator} */
    JS_OBJECT_SINGLE_FIELD_PREFIX("JO"),

    /** name for allocate method in JO objects */
    ALLOCATE("allocate"),

    /** prefix for split methods, @see Splitter */
    SPLIT_PREFIX(":split"),

    /** prefix for split array method and slot */
    SPLIT_ARRAY_ARG(":split_array", 3),

    /** get string from constant pool */
    GET_STRING(":getString"),

    /** get map */
    GET_MAP(":getMap"),

    /** set map */
    SET_MAP(":setMap"),

    /** get array prefix */
    GET_ARRAY_PREFIX(":get"),

    /** get array suffix */
    GET_ARRAY_SUFFIX("$array");

    /** To save memory - intern the compiler constant symbol names, as they are frequently reused */
    static {
        for (final CompilerConstants c : values()) {
            final String symbolName = c.symbolName();
            if (symbolName != null) {
                symbolName.intern();
            }
        }
    }

    private static Set<String> symbolNames;

    /**
     * Prefix used for internal methods generated in script classes.
     */
    private static final String INTERNAL_METHOD_PREFIX = ":";

    private final String symbolName;
    private final Class<?> type;
    private final int slot;

    private CompilerConstants() {
        this.symbolName = name();
        this.type = null;
        this.slot = -1;
    }

    private CompilerConstants(final String symbolName) {
        this(symbolName, -1);
    }

    private CompilerConstants(final String symbolName, final int slot) {
        this(symbolName, null, slot);
    }

    private CompilerConstants(final String symbolName, final Class<?> type) {
        this(symbolName, type, -1);
    }

    private CompilerConstants(final String symbolName, final Class<?> type, final int slot) {
        this.symbolName = symbolName;
        this.type       = type;
        this.slot       = slot;
    }

    /**
     * Check whether a name is that of a reserved compiler constant
     * @param name name
     * @return true if compiler constant name
     */
    public static boolean isCompilerConstant(final String name) {
        ensureSymbolNames();
        return symbolNames.contains(name);
    }

    private static void ensureSymbolNames() {
        if(symbolNames == null) {
            symbolNames = new HashSet<>();
            for(final CompilerConstants cc: CompilerConstants.values()) {
                symbolNames.add(cc.symbolName);
            }
        }
    }

    /**
     * Return the tag for this compile constant. Deliberately avoiding "name" here
     * not to conflate with enum implementation. This is the master string for the
     * constant - every constant has one.
     *
     * @return the tag
     */
    public final String symbolName() {
        return symbolName;
    }

    /**
     * Return the type for this compile constant
     *
     * @return type for this constant's instances, or null if N/A
     */
    public final Class<?> type() {
        return type;
    }

    /**
     * Return the slot for this compile constant
     *
     * @return byte code slot where constant is stored or -1 if N/A
     */
    public final int slot() {
        return slot;
    }

    /**
     * Return a descriptor for this compile constant. Only relevant if it has
     * a type
     *
     * @return descriptor the descriptor
     */
    public final String descriptor() {
        assert type != null : " asking for descriptor of typeless constant";
        return typeDescriptor(type);
    }

    /**
     * Get the internal class name for a type
     *
     * @param type a type
     * @return  the internal name for this type
     */
    public static String className(final Class<?> type) {
        return Type.getInternalName(type);
    }

    /**
     * Get the method descriptor for a given method type collection
     *
     * @param rtype  return type
     * @param ptypes parameter types
     *
     * @return internal descriptor for this method
     */
    public static String methodDescriptor(final Class<?> rtype, final Class<?>... ptypes) {
        return Type.getMethodDescriptor(rtype, ptypes);
    }

    /**
     * Get the type descriptor for a type
     *
     * @param clazz a type
     *
     * @return the internal descriptor for this type
     */
    public static String typeDescriptor(final Class<?> clazz) {
        return Type.typeFor(clazz).getDescriptor();
    }

    /**
     * Create a call representing a void constructor for a given type. Don't
     * attempt to look this up at compile time
     *
     * @param clazz the class
     *
     * @return Call representing void constructor for type
     */
    public static Call constructorNoLookup(final Class<?> clazz) {
        return specialCallNoLookup(clazz, INIT.symbolName(), void.class);
    }

    /**
     * Create a call representing a constructor for a given type. Don't
     * attempt to look this up at compile time
     *
     * @param className the type class name
     * @param ptypes    the parameter types for the constructor
     *
     * @return Call representing constructor for type
     */
    public static Call constructorNoLookup(final String className, final Class<?>... ptypes) {
        return specialCallNoLookup(className, INIT.symbolName(), methodDescriptor(void.class, ptypes));
    }

    /**
     * Create a call representing a constructor for a given type. Don't
     * attempt to look this up at compile time
     *
     * @param clazz  the class name
     * @param ptypes the parameter types for the constructor
     *
     * @return Call representing constructor for type
     */
    public static Call constructorNoLookup(final Class<?> clazz, final Class<?>... ptypes) {
        return specialCallNoLookup(clazz, INIT.symbolName(), void.class, ptypes);
    }

    /**
     * Create a call representing an invokespecial to a given method. Don't
     * attempt to look this up at compile time
     *
     * @param className the class name
     * @param name      the method name
     * @param desc      the descriptor
     *
     * @return Call representing specified invokespecial call
     */
    public static Call specialCallNoLookup(final String className, final String name, final String desc) {
        return new Call(null, className, name, desc) {
            @Override
            MethodEmitter invoke(final MethodEmitter method) {
                return method.invokespecial(className, name, descriptor);
            }

            @Override
            public void invoke(final MethodVisitor mv) {
                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, name, desc, false);
            }
        };
    }

    /**
     * Create a call representing an invokespecial to a given method. Don't
     * attempt to look this up at compile time
     *
     * @param clazz  the class
     * @param name   the method name
     * @param rtype  the return type
     * @param ptypes the parameter types
     *
     * @return Call representing specified invokespecial call
     */
    public static Call specialCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
        return specialCallNoLookup(className(clazz), name, methodDescriptor(rtype, ptypes));
    }

    /**
     * Create a call representing an invokestatic to a given method. Don't
     * attempt to look this up at compile time
     *
     * @param className the class name
     * @param name      the method name
     * @param desc      the descriptor
     *
     * @return Call representing specified invokestatic call
     */
    public static Call staticCallNoLookup(final String className, final String name, final String desc) {
        return new Call(null, className, name, desc) {
            @Override
            MethodEmitter invoke(final MethodEmitter method) {
                return method.invokestatic(className, name, descriptor);
            }

            @Override
            public void invoke(final MethodVisitor mv) {
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, name, desc, false);
            }
        };
    }

    /**
     * Create a call representing an invokestatic to a given method. Don't
     * attempt to look this up at compile time
     *
     * @param clazz  the class
     * @param name   the method name
     * @param rtype  the return type
     * @param ptypes the parameter types
     *
     * @return Call representing specified invokestatic call
     */
    public static Call staticCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
        return staticCallNoLookup(className(clazz), name, methodDescriptor(rtype, ptypes));
    }

    /**
     * Create a call representing an invokevirtual to a given method. Don't
     * attempt to look this up at compile time
     *
     * @param clazz  the class
     * @param name   the method name
     * @param rtype  the return type
     * @param ptypes the parameter types
     *
     * @return Call representing specified invokevirtual call
     */
    public static Call virtualCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
        return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
            @Override
            MethodEmitter invoke(final MethodEmitter method) {
                return method.invokevirtual(className, name, descriptor);
            }

            @Override
            public void invoke(final MethodVisitor mv) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, name, descriptor, false);
            }
        };
    }

    /**
     * Create a call representing an invokeinterface to a given method. Don't
     * attempt to look this up at compile time
     *
     * @param clazz  the class
     * @param name   the method name
     * @param rtype  the return type
     * @param ptypes the parameter types
     *
     * @return Call representing specified invokeinterface call
     */
    public static Call interfaceCallNoLookup(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
        return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
            @Override
            MethodEmitter invoke(final MethodEmitter method) {
                return method.invokeinterface(className, name, descriptor);
            }

            @Override
            public void invoke(final MethodVisitor mv) {
                mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, className, name, descriptor, true);
            }
        };
    }

    /**
     * Create a FieldAccess representing a virtual field, that can be subject to put
     * or get operations
     *
     * @param className name of the class where the field is a member
     * @param name      name of the field
     * @param desc      type descriptor of the field
     *
     * @return a field access object giving access code generation method for the virtual field
     */
    public static FieldAccess virtualField(final String className, final String name, final String desc) {
        return new FieldAccess(className, name, desc) {
            @Override
            public MethodEmitter get(final MethodEmitter method) {
                return method.getField(className, name, descriptor);
            }

            @Override
            public void put(final MethodEmitter method) {
                method.putField(className, name, descriptor);
            }
        };
    }

    /**
     * Create a FieldAccess representing a virtual field, that can be subject to put
     * or get operations
     *
     * @param clazz class where the field is a member
     * @param name  name of the field
     * @param type  type of the field
     *
     * @return a field access object giving access code generation method for the virtual field
     */
    public static FieldAccess virtualField(final Class<?> clazz, final String name, final Class<?> type) {
        return virtualField(className(clazz), name, typeDescriptor(type));
    }

    /**
     * Create a FieldAccess representing a static field, that can be subject to put
     * or get operations
     *
     * @param className name of the class where the field is a member
     * @param name      name of the field
     * @param desc      type descriptor of the field
     *
     * @return a field access object giving access code generation method for the static field
     */
    public static FieldAccess staticField(final String className, final String name, final String desc) {
        return new FieldAccess(className, name, desc) {
            @Override
            public MethodEmitter get(final MethodEmitter method) {
                return method.getStatic(className, name, descriptor);
            }

            @Override
            public void put(final MethodEmitter method) {
                method.putStatic(className, name, descriptor);
            }
        };
    }

    /**
     * Create a FieldAccess representing a static field, that can be subject to put
     * or get operations
     *
     * @param clazz class where the field is a member
     * @param name  name of the field
     * @param type  type of the field
     *
     * @return a field access object giving access code generation method for the virtual field
     */
    public static FieldAccess staticField(final Class<?> clazz, final String name, final Class<?> type) {
        return staticField(className(clazz), name, typeDescriptor(type));
    }

    /**
     * Create a static call, given an explicit lookup, looking up the method handle for it at the same time
     *
     * @param lookup the lookup
     * @param clazz  the class
     * @param name   the name of the method
     * @param rtype  the return type
     * @param ptypes the parameter types
     *
     * @return the call object representing the static call
     */
    public static Call staticCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
        return new Call(MH.findStatic(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
            @Override
            MethodEmitter invoke(final MethodEmitter method) {
                return method.invokestatic(className, name, descriptor);
            }

            @Override
            public void invoke(final MethodVisitor mv) {
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, name, descriptor, false);
            }
        };
    }

    /**
     * Create a virtual call, given an explicit lookup, looking up the method handle for it at the same time
     *
     * @param lookup the lookup
     * @param clazz  the class
     * @param name   the name of the method
     * @param rtype  the return type
     * @param ptypes the parameter types
     *
     * @return the call object representing the virtual call
     */
    public static Call virtualCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
        return new Call(MH.findVirtual(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
            @Override
            MethodEmitter invoke(final MethodEmitter method) {
                return method.invokevirtual(className, name, descriptor);
            }

            @Override
            public void invoke(final MethodVisitor mv) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, name, descriptor, false);
            }
        };
    }

    /**
     * Create a special call, given an explicit lookup, looking up the method handle for it at the same time.
     * clazz is used as this class
     *
     * @param lookup    the lookup
     * @param clazz     the class
     * @param name      the name of the method
     * @param rtype     the return type
     * @param ptypes    the parameter types
     *
     * @return the call object representing the virtual call
     */
    public static Call specialCall(final MethodHandles.Lookup lookup, final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
        return new Call(MH.findSpecial(lookup, clazz, name, MH.type(rtype, ptypes), clazz), className(clazz), name, methodDescriptor(rtype, ptypes)) {
            @Override
            MethodEmitter invoke(final MethodEmitter method) {
                return method.invokespecial(className, name, descriptor);
            }

            @Override
            public void invoke(final MethodVisitor mv) {
                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, name, descriptor, false);
            }
        };
    }

    /**
     * Returns true if the passed string looks like a method name of an internally generated Nashorn method. Basically,
     * if it starts with a colon character {@code :} but is not the name of the program method {@code :program}.
     * Program function is not considered internal as we want it to show up in exception stack traces.
     * @param methodName the name of a method
     * @return true if it looks like an internal Nashorn method name.
     * @throws NullPointerException if passed null
     */
    public static boolean isInternalMethodName(final String methodName) {
        return methodName.startsWith(INTERNAL_METHOD_PREFIX) && !methodName.equals(PROGRAM.symbolName);
     }

    /**
     * Private class representing an access. This can generate code into a method code or
     * a field access.
     */
    private abstract static class Access {
        protected final MethodHandle methodHandle;
        protected final String       className;
        protected final String       name;
        protected final String       descriptor;

        /**
         * Constructor
         *
         * @param methodHandle methodHandle or null if none
         * @param className    class name for access
         * @param name         field or method name for access
         * @param descriptor   descriptor for access field or method
         */
        protected Access(final MethodHandle methodHandle, final String className, final String name, final String descriptor) {
            this.methodHandle = methodHandle;
            this.className    = className;
            this.name         = name;
            this.descriptor   = descriptor;
        }

        /**
         * Get the method handle, or null if access hasn't been looked up
         *
         * @return method handle
         */
        public MethodHandle methodHandle() {
            return methodHandle;
        }

        /**
         * Get the class name of the access
         *
         * @return the class name
         */
        public String className() {
            return className;
        }

        /**
         * Get the field name or method name of the access
         *
         * @return the name
         */
        public String name() {
            return name;
        }

        /**
         * Get the descriptor of the method or field of the access
         *
         * @return the descriptor
         */
        public String descriptor() {
            return descriptor;
        }
    }

    /**
     * Field access - this can be used for generating code for static or
     * virtual field accesses
     */
    public abstract static class FieldAccess extends Access {
        /**
         * Constructor
         *
         * @param className  name of the class where the field is
         * @param name       name of the field
         * @param descriptor descriptor of the field
         */
        protected FieldAccess(final String className, final String name, final String descriptor) {
            super(null, className, name, descriptor);
        }

        /**
         * Generate get code for the field
         *
         * @param emitter a method emitter
         *
         * @return the method emitter
         */
        protected abstract MethodEmitter get(final MethodEmitter emitter);

        /**
         * Generate put code for the field
         *
         * @param emitter a method emitter
         */
        protected abstract void put(final MethodEmitter emitter);
    }

    /**
     * Call - this can be used for generating code for different types of calls
     */
    public abstract static class Call extends Access {

        /**
         * Constructor
         *
         * @param className  class name for the method of the call
         * @param name       method name
         * @param descriptor method descriptor
         */
        protected Call(final String className, final String name, final String descriptor) {
            super(null, className, name, descriptor);
        }

        /**
         * Constructor
         *
         * @param methodHandle method handle for the call if resolved
         * @param className    class name for the method of the call
         * @param name         method name
         * @param descriptor   method descriptor
         */
        protected Call(final MethodHandle methodHandle, final String className, final String name, final String descriptor) {
            super(methodHandle, className, name, descriptor);
        }

        /**
         * Generate invocation code for the method
         *
         * @param emitter a method emitter
         *
         * @return the method emitter
         */
        abstract MethodEmitter invoke(final MethodEmitter emitter);

        /**
         * Generate invocation code for the method
         *
         * @param mv a method visitor
         */
        public abstract void invoke(final MethodVisitor mv);
    }

}
