package org.codehaus.jackson.map.deser;

import java.util.*;

import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.type.*;

/**
 * Deserializer factory implementation that allows for configuring
 * mapping between types and deserializers to use, by using
 * multiple types of overrides. Existing mappings established by
 * {@link BeanDeserializerFactory} (and its super class,
 * {@link BasicDeserializerFactory}) are used if no overrides are
 * defined.
 *<p>
 * Unlike base deserializer factories, this factory is stateful because
 * of configuration settings. It is thread-safe, however, as long as
 * all configuration as done before using the factory -- a single
 * instance can be shared between providers and mappers.
 *<p>
 * Configurations currently available are:
 *<ul>
 * <li>Ability to define explicit mappings between simple non-generic
 *   classes/interfaces and deserializers to use for deserializing
 *   instance of these classes. Mappings are one-to-one (i.e. there is
 *   no "generic" variant for handling sub- or super-classes/interfaces).
 *  </li>
 *</ul>
 *<p>
 * The way custom deserializer factory instances are hooked to
 * {@link ObjectMapper} is usually by constructing an instance of
 * {@link DeserializerProvider} (most commonly
 * {@link StdDeserializerProvider}) with custom deserializer factory,
 * and setting {@link ObjectMapper} to use it.
 * 
 * @deprecated Starting with 1.7, functionality of this class has been
 *    implemented both in base {@link SerializerFactory} (see methods
 *    like {@link SerializerFactory#withAdditionalSerializers(Serializers)})
 *    and through new Module API. As such, this class is not the best way
 *    to add custom functionality, and will likely be removed from 2.0 release
 */
@Deprecated
public class CustomDeserializerFactory
    extends BeanDeserializerFactory
{
    /*
    /**********************************************************
    /* Configuration, direct/special mappings
    /**********************************************************
     */

    /**
     * Direct mappings that are used for exact class and interface type
     * matches.
     */
    protected HashMap<ClassKey,JsonDeserializer<Object>> _directClassMappings = null;

    /*
    /**********************************************************
    /* Configuration: mappings that define "mix-in annotations"
    /**********************************************************
     */

    /**
     * Mapping that defines how to apply mix-in annotations: key is
     * the type to received additional annotations, and value is the
     * type that has annotations to "mix in".
     *<p>
     * Annotations associated with the value classes will be used to
     * override annotations of the key class, associated with the
     * same field or method. They can be further masked by sub-classes:
     * you can think of it as injecting annotations between the target
     * class and its sub-classes (or interfaces)
     *
     * @since 1.2
     */
    protected HashMap<ClassKey,Class<?>> _mixInAnnotations;

    /*
    /**********************************************************
    /* Life-cycle, constructors
    /**********************************************************
     */

    public CustomDeserializerFactory() {
        this(null);
    }

    protected CustomDeserializerFactory(Config config)
    {
        super(config);
    }
    
    @Override
    public DeserializerFactory withConfig(Config config)
    {
        // See super-class method for reasons for this check...
        if (getClass() != CustomDeserializerFactory.class) {
            throw new IllegalStateException("Subtype of CustomDeserializerFactory ("+getClass().getName()
                    +") has not properly overridden method 'withAdditionalDeserializers': can not instantiate subtype with "
                    +"additional deserializer definitions");
        }
        return new CustomDeserializerFactory(config);
    }
    
    /*
    /**********************************************************
    /* Configuration: type-to-serializer mappings
    /**********************************************************
     */

    /**
     * Method used to add a mapping for specific type -- and only that
     * type -- to use specified deserializer.
     * This means that binding is not used for sub-types.
     *<p>
     * Note that both class and interfaces can be mapped, since the type
     * is derived from method declarations; and hence may be abstract types
     * and interfaces. This is different from custom serialization where
     * only class types can be directly mapped.
     *
     * @param forClass Class to deserialize using specific deserializer.
     * @param deser Deserializer to use for the class. Declared type for
     *   deserializer may be more specific (sub-class) than declared class
     *   to map, since that will still be compatible (deserializer produces
     *   sub-class which is assignable to field/method)
     */
    @SuppressWarnings("unchecked")
    public <T> void addSpecificMapping(Class<T> forClass, JsonDeserializer<? extends T> deser)
    {
        ClassKey key = new ClassKey(forClass);
        if (_directClassMappings == null) {
            _directClassMappings = new HashMap<ClassKey,JsonDeserializer<Object>>();
        }
        _directClassMappings.put(key, (JsonDeserializer<Object>)deser);
    }

    /**
     * Method to use for adding mix-in annotations that Class
     * <code>classWithMixIns</code> contains into class
     * <code>destinationClass</code>. Mixing in is done when introspecting
     * class annotations and properties.
     * Annotations from <code>classWithMixIns</code> (and its supertypes)
     * will <b>override</b>
     * anything <code>destinationClass</code> (and its super-types)
     * has already.
     *
     * @param destinationClass Class to modify by adding annotations
     * @param classWithMixIns Class that contains annotations to add
     *
     * @since 1.2
     */
    public void addMixInAnnotationMapping(Class<?> destinationClass,
                                          Class<?> classWithMixIns)
    {
        if (_mixInAnnotations == null) {
            _mixInAnnotations = new HashMap<ClassKey,Class<?>>();
        }
        _mixInAnnotations.put(new ClassKey(destinationClass), classWithMixIns);
    }

    /*
    /**********************************************************
    /* DeserializerFactory API
    /**********************************************************
     */

    @Override
    public JsonDeserializer<Object> createBeanDeserializer(DeserializationConfig config, DeserializerProvider p,
            JavaType type, BeanProperty property)
        throws JsonMappingException
    {
        Class<?> cls = type.getRawClass();
        ClassKey key = new ClassKey(cls);

        // Do we have a match?
        if (_directClassMappings != null) {
            JsonDeserializer<Object> deser = _directClassMappings.get(key);
            if (deser != null) {
                return deser;
            }
        }
        // If not, let super class do its job
        return super.createBeanDeserializer(config, p, type, property);
    }

    @Override
    public JsonDeserializer<?> createArrayDeserializer(DeserializationConfig config, DeserializerProvider p,
            ArrayType type, BeanProperty property)
        throws JsonMappingException
    {
        ClassKey key = new ClassKey(type.getRawClass());
        if (_directClassMappings != null) {
            JsonDeserializer<Object> deser = _directClassMappings.get(key);
            if (deser != null) {
                return deser;
            }
        }
        return super.createArrayDeserializer(config, p, type, property);
    }

    //public JsonDeserializer<?> createCollectionDeserializer(...) throws JsonMappingException

    @Override
    public JsonDeserializer<?> createEnumDeserializer(DeserializationConfig config, DeserializerProvider p,
            JavaType enumType, BeanProperty property)
        throws JsonMappingException
    {
        /* Enums can't extend anything; must be a direct
         * match, if anything:
         * (theoretically they can implement interfaces, but that seems irrelevant)
         */
        if (_directClassMappings != null) {
            ClassKey key = new ClassKey(enumType.getRawClass());
            JsonDeserializer<?> deser = _directClassMappings.get(key);
            if (deser != null) {
                return deser;
            }
        }
        return super.createEnumDeserializer(config, p, enumType, property);
    }

    //public JsonDeserializer<?> createMapDeserializer(...) throws JsonMappingException

    //public JsonDeserializer<?> createTreeDeserializer(...) throws JsonMappingException
}
