/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */

package net.ranides.assira.reflection.impl;

import java.lang.reflect.AnnotatedType;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import net.ranides.assira.reflection.IClass;
import net.ranides.assira.reflection.IContext;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public final class FClass {
    
    private static final FCache<IClass> CACHE = new FCache<>();
    
    private FClass() {
        /* utility class */
    }
       
    public static IClass<?> newClass(IContext context, Class<?> type) {
        return CACHE.get(context, type, () -> new RClass(context, type));
    }
    
    public static IClass<?> newClass(IContext context, WildcardType type) {
        return CACHE.get(context, type, () -> new RWClass(context, type));
    }

    public static IClass<?> newClass(IContext context, TypeVariable<?> type) {
        return CACHE.get(context, type, () -> new RWClass(context, type));
    }
    
    public static IClass<?> newClass(IContext context, Type itype, AnnotatedType atype) {
        if(itype instanceof GenericArrayType) {
            return FClass.newClass(context, (GenericArrayType)itype);
        } else {
            return CACHE.get(context, atype, () -> new RFClass(context, context.typeinfo(itype), atype));
        }
    }
    
    public static <R> IClass<R> newClass(IContext context, Class<R> type, ParameterizedType ptype) {
        return CACHE.get(context, ptype, () -> new RPClass(context, type, ptype));
    }
    
    public static <R> IClass<R> newClass(Class<R> type, IClass<?>[] params) {
        return new GContext(type, params).typeinfo(type);
    }
    
    public static IClass<?> newClass(IContext context, GenericArrayType gtype) {
        return new RGClass(context, gtype);
    }
    
}
