package org.checkerframework.javacutil;

import static com.sun.tools.javac.code.TypeTag.WILDCARD;

import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.Context;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.WildcardType;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

/** A utility class that helps with {@link TypeMirror}s. */
// TODO: This class needs significant restructuring
public final class TypesUtils {

    // Class cannot be instantiated
    private TypesUtils() {
        throw new AssertionError("Class TypesUtils cannot be instantiated.");
    }

    /**
     * Gets the fully qualified name for a provided type. It returns an empty name if type is an
     * anonymous type.
     *
     * @param type the declared type
     * @return the name corresponding to that type
     */
    public static Name getQualifiedName(DeclaredType type) {
        TypeElement element = (TypeElement) type.asElement();
        return element.getQualifiedName();
    }

    /**
     * Checks if the type represents a java.lang.Object declared type.
     *
     * @param type the type
     * @return true iff type represents java.lang.Object
     */
    public static boolean isObject(TypeMirror type) {
        return isDeclaredOfName(type, "java.lang.Object");
    }

    /**
     * Checks if the type represents a java.lang.Class declared type.
     *
     * @param type the type
     * @return true iff type represents java.lang.Class
     */
    public static boolean isClass(TypeMirror type) {
        return isDeclaredOfName(type, "java.lang.Class");
    }

    /**
     * Checks if the type represents a java.lang.String declared type. TODO: it would be cleaner to
     * use String.class.getCanonicalName(), but the two existing methods above don't do that, I
     * guess for performance reasons.
     *
     * @param type the type
     * @return true iff type represents java.lang.String
     */
    public static boolean isString(TypeMirror type) {
        return isDeclaredOfName(type, "java.lang.String");
    }

    /**
     * Checks if the type represents a boolean type, that is either boolean (primitive type) or
     * java.lang.Boolean.
     *
     * @param type the type to test
     * @return true iff type represents a boolean type
     */
    public static boolean isBooleanType(TypeMirror type) {
        return isDeclaredOfName(type, "java.lang.Boolean")
                || type.getKind().equals(TypeKind.BOOLEAN);
    }

    /**
     * Check if the type represent a declared type of the given qualified name
     *
     * @param type the type
     * @return type iff type represents a declared type of the qualified name
     */
    public static boolean isDeclaredOfName(TypeMirror type, CharSequence qualifiedName) {
        return type.getKind() == TypeKind.DECLARED
                && getQualifiedName((DeclaredType) type).contentEquals(qualifiedName);
    }

    public static boolean isBoxedPrimitive(TypeMirror type) {
        if (type.getKind() != TypeKind.DECLARED) {
            return false;
        }

        String qualifiedName = getQualifiedName((DeclaredType) type).toString();

        return (qualifiedName.equals("java.lang.Boolean")
                || qualifiedName.equals("java.lang.Byte")
                || qualifiedName.equals("java.lang.Character")
                || qualifiedName.equals("java.lang.Short")
                || qualifiedName.equals("java.lang.Integer")
                || qualifiedName.equals("java.lang.Long")
                || qualifiedName.equals("java.lang.Double")
                || qualifiedName.equals("java.lang.Float"));
    }

    /** @return type represents a Throwable type (e.g. Exception, Error) */
    public static boolean isThrowable(TypeMirror type) {
        while (type != null && type.getKind() == TypeKind.DECLARED) {
            DeclaredType dt = (DeclaredType) type;
            TypeElement elem = (TypeElement) dt.asElement();
            Name name = elem.getQualifiedName();
            if ("java.lang.Throwable".contentEquals(name)) {
                return true;
            }
            type = elem.getSuperclass();
        }
        return false;
    }

    /**
     * Returns true iff the argument is an anonymous type.
     *
     * @return whether the argument is an anonymous type
     */
    public static boolean isAnonymous(TypeMirror type) {
        return (type instanceof DeclaredType)
                && (((TypeElement) ((DeclaredType) type).asElement())
                        .getNestingKind()
                        .equals(NestingKind.ANONYMOUS));
    }

    /**
     * Returns true iff the argument is a primitive type.
     *
     * @return whether the argument is a primitive type
     */
    public static boolean isPrimitive(TypeMirror type) {
        switch (type.getKind()) {
            case BOOLEAN:
            case BYTE:
            case CHAR:
            case DOUBLE:
            case FLOAT:
            case INT:
            case LONG:
            case SHORT:
                return true;
            default:
                return false;
        }
    }

    /**
     * Returns true iff the arguments are both the same primitive types.
     *
     * @return whether the arguments are the same primitive types
     */
    public static boolean areSamePrimitiveTypes(TypeMirror left, TypeMirror right) {
        if (!isPrimitive(left) || !isPrimitive(right)) {
            return false;
        }

        return (left.getKind() == right.getKind());
    }

    /**
     * Returns true iff the argument is a primitive numeric type.
     *
     * @return whether the argument is a primitive numeric type
     */
    public static boolean isNumeric(TypeMirror type) {
        switch (type.getKind()) {
            case BYTE:
            case CHAR:
            case DOUBLE:
            case FLOAT:
            case INT:
            case LONG:
            case SHORT:
                return true;
            default:
                return false;
        }
    }

    /**
     * Returns true iff the argument is an integral type.
     *
     * @return whether the argument is an integral type
     */
    public static boolean isIntegral(TypeMirror type) {
        switch (type.getKind()) {
            case BYTE:
            case CHAR:
            case INT:
            case LONG:
            case SHORT:
                return true;
            default:
                return false;
        }
    }

    /**
     * Returns true iff the argument is a floating point type.
     *
     * @return whether the argument is a floating point type
     */
    public static boolean isFloating(TypeMirror type) {
        switch (type.getKind()) {
            case DOUBLE:
            case FLOAT:
                return true;
            default:
                return false;
        }
    }

    /**
     * Returns the widened numeric type for an arithmetic operation performed on a value of the left
     * type and the right type. Defined in JLS 5.6.2. We return a {@link TypeKind} because creating
     * a {@link TypeMirror} requires a {@link Types} object from the {@link
     * javax.annotation.processing.ProcessingEnvironment}.
     *
     * @return the result of widening numeric conversion, or NONE when the conversion cannot be
     *     performed
     */
    public static TypeKind widenedNumericType(TypeMirror left, TypeMirror right) {
        if (!isNumeric(left) || !isNumeric(right)) {
            return TypeKind.NONE;
        }

        TypeKind leftKind = left.getKind();
        TypeKind rightKind = right.getKind();

        if (leftKind == TypeKind.DOUBLE || rightKind == TypeKind.DOUBLE) {
            return TypeKind.DOUBLE;
        }

        if (leftKind == TypeKind.FLOAT || rightKind == TypeKind.FLOAT) {
            return TypeKind.FLOAT;
        }

        if (leftKind == TypeKind.LONG || rightKind == TypeKind.LONG) {
            return TypeKind.LONG;
        }

        return TypeKind.INT;
    }

    /**
     * If the argument is a bounded TypeVariable or WildcardType, return its non-variable,
     * non-wildcard upper bound. Otherwise, return the type itself.
     *
     * @param type a type
     * @return the non-variable, non-wildcard upper bound of a type, if it has one, or itself if it
     *     has no bounds
     */
    public static TypeMirror upperBound(TypeMirror type) {
        do {
            if (type instanceof TypeVariable) {
                TypeVariable tvar = (TypeVariable) type;
                if (tvar.getUpperBound() != null) {
                    type = tvar.getUpperBound();
                } else {
                    break;
                }
            } else if (type instanceof WildcardType) {
                WildcardType wc = (WildcardType) type;
                if (wc.getExtendsBound() != null) {
                    type = wc.getExtendsBound();
                } else {
                    break;
                }
            } else {
                break;
            }
        } while (true);
        return type;
    }

    /**
     * Get the type parameter for this wildcard from the underlying type's bound field This field is
     * sometimes null, in that case this method will return null
     *
     * @return the TypeParameterElement the wildcard is an argument to
     */
    public static TypeParameterElement wildcardToTypeParam(final Type.WildcardType wildcard) {

        final Element typeParamElement;
        if (wildcard.bound != null) {
            typeParamElement = wildcard.bound.asElement();
        } else {
            typeParamElement = null;
        }

        return (TypeParameterElement) typeParamElement;
    }

    /**
     * Version of com.sun.tools.javac.code.Types.wildUpperBound(Type) that works with both jdk8
     * (called upperBound there) and jdk8u.
     */
    // TODO: contrast to upperBound.
    public static Type wildUpperBound(ProcessingEnvironment env, TypeMirror tm) {
        Type t = (Type) tm;
        if (t.hasTag(TypeTag.WILDCARD)) {
            Context context = ((JavacProcessingEnvironment) env).getContext();
            Type.WildcardType w = (Type.WildcardType) TypeAnnotationUtils.unannotatedType(t);
            if (w.isSuperBound()) {
                Symtab syms = Symtab.instance(context);
                return w.bound == null ? syms.objectType : w.bound.bound;
            } else {
                return wildUpperBound(env, w.type);
            }
        } else {
            return TypeAnnotationUtils.unannotatedType(t);
        }
    }

    /**
     * Version of com.sun.tools.javac.code.Types.wildLowerBound(Type) that works with both jdk8
     * (called upperBound there) and jdk8u.
     */
    public static Type wildLowerBound(ProcessingEnvironment env, TypeMirror tm) {
        Type t = (Type) tm;
        if (t.hasTag(WILDCARD)) {
            Context context = ((JavacProcessingEnvironment) env).getContext();
            Symtab syms = Symtab.instance(context);
            Type.WildcardType w = (Type.WildcardType) TypeAnnotationUtils.unannotatedType(t);
            return w.isExtendsBound() ? syms.botType : wildLowerBound(env, w.type);
        } else {
            return TypeAnnotationUtils.unannotatedType(t);
        }
    }
    /** Returns the {@link TypeMirror} for a given {@link Class}. */
    public static TypeMirror typeFromClass(Types types, Elements elements, Class<?> clazz) {
        if (clazz == void.class) {
            return types.getNoType(TypeKind.VOID);
        } else if (clazz.isPrimitive()) {
            String primitiveName = clazz.getName().toUpperCase();
            TypeKind primitiveKind = TypeKind.valueOf(primitiveName);
            return types.getPrimitiveType(primitiveKind);
        } else if (clazz.isArray()) {
            TypeMirror componentType = typeFromClass(types, elements, clazz.getComponentType());
            return types.getArrayType(componentType);
        } else {
            TypeElement element = elements.getTypeElement(clazz.getCanonicalName());
            if (element == null) {
                ErrorReporter.errorAbort("Unrecognized class: " + clazz);
                return null; // dead code
            }
            return element.asType();
        }
    }

    /** Returns an {@link ArrayType} with elements of type {@code componentType}. */
    public static ArrayType createArrayType(Types types, TypeMirror componentType) {
        JavacTypes t = (JavacTypes) types;
        return t.getArrayType(componentType);
    }

    /**
     * Returns true if declaredType is a Class that is used to box primitive type (e.g.
     * declaredType=java.lang.Double and primitiveType=22.5d )
     */
    public static boolean isBoxOf(TypeMirror declaredType, TypeMirror primitiveType) {
        if (declaredType.getKind() != TypeKind.DECLARED) {
            return false;
        }

        final String qualifiedName = getQualifiedName((DeclaredType) declaredType).toString();
        switch (primitiveType.getKind()) {
            case BOOLEAN:
                return qualifiedName.equals("java.lang.Boolean");
            case BYTE:
                return qualifiedName.equals("java.lang.Byte");
            case CHAR:
                return qualifiedName.equals("java.lang.Character");
            case DOUBLE:
                return qualifiedName.equals("java.lang.Double");
            case FLOAT:
                return qualifiedName.equals("java.lang.Float");
            case INT:
                return qualifiedName.equals("java.lang.Integer");
            case LONG:
                return qualifiedName.equals("java.lang.Long");
            case SHORT:
                return qualifiedName.equals("java.lang.Short");

            default:
                return false;
        }
    }

    /**
     * Given a bounded type (wildcard or typevar) get the concrete type of its upper bound. If the
     * bounded type extends other bounded types, this method will iterate through their bounds until
     * a class, interface, or intersection is found.
     *
     * @return a type that is not a wildcard or typevar, or null if this type is an unbounded
     *     wildcard
     */
    public static TypeMirror findConcreteUpperBound(final TypeMirror boundedType) {
        TypeMirror effectiveUpper = boundedType;
        outerLoop:
        while (true) {
            switch (effectiveUpper.getKind()) {
                case WILDCARD:
                    effectiveUpper =
                            ((javax.lang.model.type.WildcardType) effectiveUpper).getExtendsBound();
                    if (effectiveUpper == null) {
                        return null;
                    }
                    break;

                case TYPEVAR:
                    effectiveUpper = ((TypeVariable) effectiveUpper).getUpperBound();
                    break;

                default:
                    break outerLoop;
            }
        }
        return effectiveUpper;
    }

    /**
     * Returns true if the erased type of subtype is a subtype of the erased type of supertype.
     *
     * @param types Types
     * @param subtype possible subtype
     * @param supertype possible supertype
     * @return true if the erased type of subtype is a subtype of the erased type of supertype
     */
    public static boolean isErasedSubtype(Types types, TypeMirror subtype, TypeMirror supertype) {
        return types.isSubtype(types.erasure(subtype), types.erasure(supertype));
    }
}
