/*
 *  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.codehaus.groovy.ast;

import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.GString;
import groovy.lang.GroovyInterceptable;
import groovy.lang.GroovyObject;
import groovy.lang.GroovyObjectSupport;
import groovy.lang.MetaClass;
import groovy.lang.Range;
import groovy.lang.Reference;
import groovy.lang.Script;
import groovy.lang.Tuple;
import groovy.lang.Tuple0;
import groovy.lang.Tuple1;
import groovy.lang.Tuple10;
import groovy.lang.Tuple11;
import groovy.lang.Tuple12;
import groovy.lang.Tuple13;
import groovy.lang.Tuple14;
import groovy.lang.Tuple15;
import groovy.lang.Tuple16;
import groovy.lang.Tuple2;
import groovy.lang.Tuple3;
import groovy.lang.Tuple4;
import groovy.lang.Tuple5;
import groovy.lang.Tuple6;
import groovy.lang.Tuple7;
import groovy.lang.Tuple8;
import groovy.lang.Tuple9;
import org.apache.groovy.util.Maps;
import org.codehaus.groovy.classgen.asm.util.TypeUtil;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.GeneratedLambda;
import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
import org.codehaus.groovy.transform.trait.Traits;
import org.codehaus.groovy.util.ManagedConcurrentMap;
import org.codehaus.groovy.util.ReferenceBundle;
import org.codehaus.groovy.vmplugin.VMPluginFactory;
import org.objectweb.asm.Opcodes;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.invoke.SerializedLambda;
import java.lang.ref.SoftReference;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Helper for {@link ClassNode} and classes handling them.  Contains a set of
 * pre-defined instances for the most used types and some code for cached node
 * creation and basic handling.
 */
public class ClassHelper {

    private static final Class[] classes = new Class[]{
            Object.class, Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE,
            Integer.TYPE, Long.TYPE, Double.TYPE, Float.TYPE, Void.TYPE,
            Closure.class, GString.class, List.class, Map.class, Range.class,
            Pattern.class, Script.class, String.class, Boolean.class,
            Character.class, Byte.class, Short.class, Integer.class, Long.class,
            Double.class, Float.class, BigDecimal.class, BigInteger.class,
            Number.class, Void.class, Reference.class, Class.class, MetaClass.class,
            Iterator.class, GeneratedClosure.class, GeneratedLambda.class, GroovyObjectSupport.class
    };

    public static final Class[] TUPLE_CLASSES = new Class[]{
            Tuple0.class, Tuple1.class, Tuple2.class, Tuple3.class, Tuple4.class, Tuple5.class, Tuple6.class,
            Tuple7.class, Tuple8.class, Tuple9.class, Tuple10.class, Tuple11.class, Tuple12.class, Tuple13.class,
            Tuple14.class, Tuple15.class, Tuple16.class
    };

    private static final String[] primitiveClassNames = new String[]{
            "", "boolean", "char", "byte", "short", "int", "long", "double", "float", "void"
    };

    public static final ClassNode
            DYNAMIC_TYPE = makeCached(Object.class),
            OBJECT_TYPE = DYNAMIC_TYPE,
            CLOSURE_TYPE = makeCached(Closure.class),
            SERIALIZEDLAMBDA_TYPE = makeCached(SerializedLambda .class),
            GSTRING_TYPE = makeCached(GString.class),
            RANGE_TYPE = makeCached(Range.class),
            PATTERN_TYPE = makeCached(Pattern.class),
            STRING_TYPE = makeCached(String.class),
            SCRIPT_TYPE = makeCached(Script.class),
            BINDING_TYPE = makeCached(Binding.class),

            boolean_TYPE = makeCached(boolean.class),
            char_TYPE = makeCached(char.class),
            byte_TYPE = makeCached(byte.class),
            int_TYPE = makeCached(int.class),
            long_TYPE = makeCached(long.class),
            short_TYPE = makeCached(short.class),
            double_TYPE = makeCached(double.class),
            float_TYPE = makeCached(float.class),
            Byte_TYPE = makeCached(Byte.class),
            Short_TYPE = makeCached(Short.class),
            Integer_TYPE = makeCached(Integer.class),
            Long_TYPE = makeCached(Long.class),
            Character_TYPE = makeCached(Character.class),
            Float_TYPE = makeCached(Float.class),
            Double_TYPE = makeCached(Double.class),
            Boolean_TYPE = makeCached(Boolean.class),
            BigInteger_TYPE = makeCached(java.math.BigInteger.class),
            BigDecimal_TYPE = makeCached(java.math.BigDecimal.class),
            Number_TYPE = makeCached(Number.class),

            VOID_TYPE = makeCached(Void.TYPE),
            void_WRAPPER_TYPE = makeCached(Void.class),
            METACLASS_TYPE = makeCached(MetaClass.class),
            Iterator_TYPE = makeCached(Iterator.class),
            Annotation_TYPE = makeCached(Annotation.class),
            ELEMENT_TYPE_TYPE = makeCached(ElementType.class),
            AUTOCLOSEABLE_TYPE = makeCached(AutoCloseable.class),
            SERIALIZABLE_TYPE = makeCached(Serializable.class),

            // uncached constants
            MAP_TYPE = makeWithoutCaching(Map.class),
            LIST_TYPE = makeWithoutCaching(List.class),
            Enum_Type = makeWithoutCaching(Enum.class),
            CLASS_Type = makeWithoutCaching(Class.class),
            TUPLE_TYPE = makeWithoutCaching(Tuple.class),
            REFERENCE_TYPE = makeWithoutCaching(Reference.class),
            COMPARABLE_TYPE = makeWithoutCaching(Comparable.class),
            GROOVY_OBJECT_TYPE = makeWithoutCaching(GroovyObject.class),
            GENERATED_LAMBDA_TYPE = makeWithoutCaching(GeneratedLambda.class),
            GENERATED_CLOSURE_Type = makeWithoutCaching(GeneratedClosure.class),
            GROOVY_INTERCEPTABLE_TYPE = makeWithoutCaching(GroovyInterceptable.class),
            GROOVY_OBJECT_SUPPORT_TYPE = makeWithoutCaching(GroovyObjectSupport.class);

    private static final ClassNode[] types = new ClassNode[]{
            OBJECT_TYPE,
            boolean_TYPE, char_TYPE, byte_TYPE, short_TYPE,
            int_TYPE, long_TYPE, double_TYPE, float_TYPE,
            VOID_TYPE, CLOSURE_TYPE, GSTRING_TYPE,
            LIST_TYPE, MAP_TYPE, RANGE_TYPE, PATTERN_TYPE,
            SCRIPT_TYPE, STRING_TYPE, Boolean_TYPE, Character_TYPE,
            Byte_TYPE, Short_TYPE, Integer_TYPE, Long_TYPE,
            Double_TYPE, Float_TYPE, BigDecimal_TYPE, BigInteger_TYPE,
            Number_TYPE,
            void_WRAPPER_TYPE, REFERENCE_TYPE, CLASS_Type, METACLASS_TYPE,
            Iterator_TYPE, GENERATED_CLOSURE_Type, GENERATED_LAMBDA_TYPE, GROOVY_OBJECT_SUPPORT_TYPE,
            GROOVY_OBJECT_TYPE, GROOVY_INTERCEPTABLE_TYPE, Enum_Type, Annotation_TYPE
    };

    private static final int ABSTRACT_STATIC_PRIVATE = Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE;
    private static final int VISIBILITY = 5; // public|protected

    protected static final ClassNode[] EMPTY_TYPE_ARRAY = {};

    public static final String OBJECT = "java.lang.Object";

    public static ClassNode makeCached(Class c) {
        final SoftReference<ClassNode> classNodeSoftReference = ClassHelperCache.classCache.get(c);
        ClassNode classNode;
        if (classNodeSoftReference == null || (classNode = classNodeSoftReference.get()) == null) {
            classNode = new ClassNode(c);
            ClassHelperCache.classCache.put(c, new SoftReference<ClassNode>(classNode));
            VMPluginFactory.getPlugin().setAdditionalClassInformation(classNode);
        }
        return classNode;
    }

    /**
     * Creates an array of ClassNodes using an array of classes.
     * For each of the given classes a new ClassNode will be
     * created
     *
     * @param classes an array of classes used to create the ClassNodes
     * @return an array of ClassNodes
     * @see #make(Class)
     */
    public static ClassNode[] make(Class[] classes) {
        ClassNode[] cns = new ClassNode[classes.length];
        for (int i = 0; i < cns.length; i++) {
            cns[i] = make(classes[i]);
        }
        return cns;
    }

    /**
     * Creates a ClassNode using a given class.
     * A new ClassNode object is only created if the class
     * is not one of the predefined ones
     *
     * @param c class used to created the ClassNode
     * @return ClassNode instance created from the given class
     */
    public static ClassNode make(Class c) {
        return make(c, true);
    }

    public static ClassNode make(Class c, boolean includeGenerics) {
        for (int i = 0; i < classes.length; i++) {
            if (c == classes[i]) return types[i];
        }
        if (c.isArray()) {
            ClassNode cn = make(c.getComponentType(), includeGenerics);
            return cn.makeArray();
        }
        return makeWithoutCaching(c, includeGenerics);
    }

    public static ClassNode makeWithoutCaching(Class c) {
        return makeWithoutCaching(c, true);
    }

    public static ClassNode makeWithoutCaching(Class c, boolean includeGenerics) {
        if (c.isArray()) {
            ClassNode cn = makeWithoutCaching(c.getComponentType(), includeGenerics);
            return cn.makeArray();
        }

        final ClassNode cached = makeCached(c);
        if (includeGenerics) {
            return cached;
        } else {
            ClassNode t = makeWithoutCaching(c.getName());
            t.setRedirect(cached);
            return t;
        }
    }

    /**
     * Creates a ClassNode using a given class.
     * Unlike make(String) this method will not use the cache
     * to create the ClassNode. This means the ClassNode created
     * from this method using the same name will have a different
     * reference
     *
     * @param name of the class the ClassNode is representing
     * @see #make(String)
     */
    public static ClassNode makeWithoutCaching(String name) {
        ClassNode cn = new ClassNode(name, Opcodes.ACC_PUBLIC, OBJECT_TYPE);
        cn.isPrimaryNode = false;
        return cn;
    }

    /**
     * Creates a ClassNode using a given class.
     * If the name is one of the predefined ClassNodes then the
     * corresponding ClassNode instance will be returned. If the
     * name is null or of length 0 the dynamic type is returned
     *
     * @param name of the class the ClassNode is representing
     */
    public static ClassNode make(String name) {
        if (name == null || name.length() == 0) return DYNAMIC_TYPE;

        for (int i = 0; i < primitiveClassNames.length; i++) {
            if (primitiveClassNames[i].equals(name)) return types[i];
        }

        for (int i = 0; i < classes.length; i++) {
            String cname = classes[i].getName();
            if (name.equals(cname)) return types[i];
        }
        return makeWithoutCaching(name);
    }

    private static final Map<ClassNode, ClassNode> PRIMITIVE_TYPE_TO_WRAPPER_TYPE_MAP = Maps.of(
            boolean_TYPE, Boolean_TYPE,
            byte_TYPE, Byte_TYPE,
            char_TYPE, Character_TYPE,
            short_TYPE, Short_TYPE,
            int_TYPE, Integer_TYPE,
            long_TYPE, Long_TYPE,
            float_TYPE, Float_TYPE,
            double_TYPE, Double_TYPE,
            VOID_TYPE, void_WRAPPER_TYPE
    );

    /**
     * Creates a ClassNode containing the wrapper of a ClassNode
     * of primitive type. Any ClassNode representing a primitive
     * type should be created using the predefined types used in
     * class. The method will check the parameter for known
     * references of ClassNode representing a primitive type. If
     * Reference is found, then a ClassNode will be contained that
     * represents the wrapper class. For example for boolean, the
     * wrapper class is java.lang.Boolean.
     * <p>
     * If the parameter is no primitive type, the redirected
     * ClassNode will be returned
     *
     * @param cn the ClassNode containing a possible primitive type
     * @see #make(Class)
     * @see #make(String)
     */
    public static ClassNode getWrapper(ClassNode cn) {
        cn = cn.redirect();
        if (!isPrimitiveType(cn)) return cn;

        ClassNode result = PRIMITIVE_TYPE_TO_WRAPPER_TYPE_MAP.get(cn);

        if (null != result) {
            return result;
        }

        return cn;
    }

    private static final Map<ClassNode, ClassNode> WRAPPER_TYPE_TO_PRIMITIVE_TYPE_MAP = Maps.inverse(PRIMITIVE_TYPE_TO_WRAPPER_TYPE_MAP);

    public static ClassNode getUnwrapper(ClassNode cn) {
        cn = cn.redirect();
        if (isPrimitiveType(cn)) return cn;

        ClassNode result = WRAPPER_TYPE_TO_PRIMITIVE_TYPE_MAP.get(cn);

        if (null != result) {
            return result;
        }

        return cn;
    }

    /**
     * Test to determine if a ClassNode is a primitive type.
     * Note: this only works for ClassNodes created using a
     * predefined ClassNode
     *
     * @param cn the ClassNode containing a possible primitive type
     * @return true if the ClassNode is a primitive type
     * @see #make(Class)
     * @see #make(String)
     */
    public static boolean isPrimitiveType(ClassNode cn) {
        return TypeUtil.isPrimitiveType(cn);
    }

    /**
     * Test to determine if a ClassNode is a type belongs to the list of types which
     * are allowed to initialize constants directly in bytecode instead of using &lt;cinit&gt;
     * <p>
     * Note: this only works for ClassNodes created using a
     * predefined ClassNode
     *
     * @param cn the ClassNode to be tested
     * @return true if the ClassNode is of int, float, long, double or String type
     * @see #make(Class)
     * @see #make(String)
     */
    public static boolean isStaticConstantInitializerType(ClassNode cn) {
        cn = cn.redirect();
        return cn == int_TYPE ||
                cn == float_TYPE ||
                cn == long_TYPE ||
                cn == double_TYPE ||
                cn == STRING_TYPE ||
                // the next items require conversion to int when initializing
                cn == byte_TYPE ||
                cn == char_TYPE ||
                cn == short_TYPE;
    }

    public static boolean isNumberType(ClassNode cn) {
        cn = cn.redirect();
        return cn == Byte_TYPE ||
                cn == Short_TYPE ||
                cn == Integer_TYPE ||
                cn == Long_TYPE ||
                cn == Float_TYPE ||
                cn == Double_TYPE ||
                cn == byte_TYPE ||
                cn == short_TYPE ||
                cn == int_TYPE ||
                cn == long_TYPE ||
                cn == float_TYPE ||
                cn == double_TYPE;
    }

    public static ClassNode makeReference() {
        return REFERENCE_TYPE.getPlainNodeReference();
    }

    public static boolean isCachedType(ClassNode type) {
        for (ClassNode cachedType : types) {
            if (cachedType == type) return true;
        }
        return false;
    }

    static class ClassHelperCache {
        static ManagedConcurrentMap<Class, SoftReference<ClassNode>> classCache = new ManagedConcurrentMap<Class, SoftReference<ClassNode>>(ReferenceBundle.getWeakBundle());
    }

    public static boolean isSAMType(ClassNode type) {
        return findSAM(type) != null;
    }

    public static boolean isFunctionalInterface(ClassNode type) {
        // Functional interface must be an interface at first, or the following exception will occur:
        // java.lang.invoke.LambdaConversionException: Functional interface SamCallable is not an interface
        return type.isInterface() && isSAMType(type);
    }

    /**
     * Returns the single abstract method of a class node, if it is a SAM type, or null otherwise.
     *
     * @param type a type for which to search for a single abstract method
     * @return the method node if type is a SAM type, null otherwise
     */
    public static MethodNode findSAM(ClassNode type) {
        if (!Modifier.isAbstract(type.getModifiers())) return null;
        if (type.isInterface()) {
            List<MethodNode> methods;
            if (type.isInterface()) {
                // e.g. BinaryOperator extends BiFunction, BinaryOperator contains no abstract method, but it is really a SAM
                methods = type.redirect().getAllDeclaredMethods();
            } else {
                methods = type.getMethods();
            }

            MethodNode found = null;
            for (MethodNode mi : methods) {
                // ignore methods, that are not abstract and from Object
                if (!Modifier.isAbstract(mi.getModifiers())) continue;
                // ignore trait methods which have a default implementation
                if (Traits.hasDefaultImplementation(mi)) continue;
                if (mi.getDeclaringClass().equals(OBJECT_TYPE)) continue;
                if (OBJECT_TYPE.getDeclaredMethod(mi.getName(), mi.getParameters()) != null) continue;

                // we have two methods, so no SAM
                if (found != null) return null;
                found = mi;
            }
            return found;

        } else {
            MethodNode found = null;
            for (MethodNode mi : type.getAbstractMethods()) {
                if (!hasUsableImplementation(type, mi)) {
                    if (found != null) return null;
                    found = mi;
                }
            }
            return found;
        }
    }

    private static boolean hasUsableImplementation(ClassNode c, MethodNode m) {
        if (c == m.getDeclaringClass()) return false;
        MethodNode found = c.getDeclaredMethod(m.getName(), m.getParameters());
        if (found == null) return false;
        int asp = found.getModifiers() & ABSTRACT_STATIC_PRIVATE;
        int visible = found.getModifiers() & VISIBILITY;
        if (visible != 0 && asp == 0) return true;
        if (c.equals(OBJECT_TYPE)) return false;
        return hasUsableImplementation(c.getSuperClass(), m);
    }

    /**
     * Returns a super class or interface for a given class depending on a given target.
     * If the target is no super class or interface, then null will be returned.
     * For a non-primitive array type, returns an array of the componentType's super class
     * or interface if the target is also an array.
     *
     * @param clazz     the start class
     * @param goalClazz the goal class
     * @return the next super class or interface
     */
    public static ClassNode getNextSuperClass(ClassNode clazz, ClassNode goalClazz) {
        if (clazz.isArray()) {
            if (!goalClazz.isArray()) return null;
            ClassNode cn = getNextSuperClass(clazz.getComponentType(), goalClazz.getComponentType());
            if (cn != null) cn = cn.makeArray();
            return cn;
        }

        if (!goalClazz.isInterface()) {
            if (clazz.isInterface()) {
                if (OBJECT_TYPE.equals(clazz)) return null;
                return OBJECT_TYPE;
            } else {
                return clazz.getUnresolvedSuperClass();
            }
        }

        ClassNode[] interfaces = clazz.getUnresolvedInterfaces();
        for (ClassNode anInterface : interfaces) {
            if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(anInterface, goalClazz)) {
                return anInterface;
            }
        }
        //none of the interfaces here match, so continue with super class
        return clazz.getUnresolvedSuperClass();
    }
}
