package net.ranides.assira.reflection;

import net.ranides.assira.collection.prototype.PrototypeMap;

import java.util.Collections;
import java.util.Map;

/**
 * This interface allows you instruct ResolvePattern how to work with your custom object.
 *
 * By default ResolvePattern uses {@link BeanModel#fluent(Object)}
 * to read properties from object.
 *
 * If your class implements this interface, then ResolvePattern
 * will use map returned by {@link #getResolveMap} instead.
 *
 * ResolveContext represents immutable objects.
 * You can't implement custom "write" behaviour.
 * In such cases, you have 3 options:
 *  - just follow JavaBean convention
 *  - just implement Map interface.
 *  - implement your own ResolveModel and register it inside ResolveConfiguration
 *
 * This interface is useful if you DON'T want to implement Map interface,
 * because it can trigger special behaviour of other framework. And you don't
 * want to write custom ResolveModel
 *
 *
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
public interface ResolveContext {

    /**
     * Empty immutable ResolveContext
     */
    ResolveContext EMPTY = () -> Collections.emptyMap();

    /**
     * Returns Map which is read-only view of this object.
     * ResolvePattern will try to read properties from this map instead of
     * invoking methods or getters.
     *
     * Please note that this method should be cheap, because it can be invoked
     * a lot of times by resolver. It should be rather "view" than "copy" of object.
     * Some form of virtual map is preferred.
     *
     * @return Map
     */
    Map<Object, Object> getResolveMap();

}
