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

package net.ranides.assira.reflection.impl;

import lombok.experimental.UtilityClass;

import java.lang.reflect.Field;

import net.ranides.assira.collection.maps.Cache;
import net.ranides.assira.reflection.IContext;
import net.ranides.assira.reflection.IField;

/**
 * This is internal factory for IField implementations.
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
@UtilityClass
public final class FField {
    
    private static final Cache<Object, IField> D_CACHE = Cache.getInstance();
    private static final Cache<Object, IField> R_CACHE = Cache.getInstance();

    /**
     * Creates IField for provided reflective field using context for type resolution.
     * Please note, that there is distinction between declared and inherited fields.
     *
     * @param declared declared
     * @param context context
     * @param field field
     * @return IField
     */
    public static IField newField(boolean declared, IContext context, Field field) {
        return (declared ? D_CACHE : R_CACHE).get(field, () -> new RField(declared, context, field));
    }

    /**
     * Creates IField for provided declared reflective field using context for type resolution.
     *
     * @param context context
     * @param field field
     * @return IField
     */
    public static IField newField(IContext context, Field field) {
        return newField(true, context, field);
    }
    
}
