package org.codehaus.jackson.map.deser.impl;

import java.io.IOException;
import java.lang.annotation.Annotation;

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.TypeDeserializer;
import org.codehaus.jackson.map.deser.SettableBeanProperty;
import org.codehaus.jackson.map.introspect.AnnotatedMember;
import org.codehaus.jackson.map.introspect.AnnotatedParameter;
import org.codehaus.jackson.map.util.Annotations;
import org.codehaus.jackson.type.JavaType;

/**
 * This concrete sub-class implements property that is passed
 * via Creator (constructor or static factory method).
 * It is not a full-featured implementation in that its set method
 * should never be called -- instead, value must separately passed.
 *<p>
 * Note on injectable values (1.9): unlike with other mutators, where
 * deserializer and injecting are separate, here we deal the two as related
 * things. This is necessary to add proper priority, as well as to simplify
 * coordination.
 *<p>
 * Note that this class was moved in Jackson 1.9
 * from being a static sub-class of "org.codehaus.jackson.map.deser.SettableBeanProperty"
 * into separate class, to make it easier to use it for custom creators.
 */
public class CreatorProperty
    extends SettableBeanProperty
{
    /**
     * Placeholder that represents constructor parameter, when it is created
     * from actual constructor.
     * May be null when a synthetic instance is created.
     */
    protected final AnnotatedParameter _annotated;

    /**
     * Id of value to inject, if value injection should be used for this parameter
     * (in addition to, or instead of, regular deserialization).
     * 
     * @since 1.9
     */
    protected final Object _injectableValueId;
    
    /**
     * @param name Name of the logical property
     * @param type Type of the property, used to find deserializer
     * @param typeDeser Type deserializer to use for handling polymorphic type
     *    information, if one is needed
     * @param contextAnnotations Contextual annotations (usually by class that
     *    declares creator [constructor, factory method] that includes
     *    this property)
     * @param param Representation of property, constructor or factory
     *    method parameter; used for accessing annotations of the property
     */
    public CreatorProperty(String name, JavaType type, TypeDeserializer typeDeser,
            Annotations contextAnnotations, AnnotatedParameter param,
            int index, Object injectableValueId)
    {
        super(name, type, typeDeser, contextAnnotations);
        _annotated = param;
        _propertyIndex = index;
        _injectableValueId = injectableValueId;
    }

    protected CreatorProperty(CreatorProperty src, JsonDeserializer<Object> deser) {
        super(src, deser);
        _annotated = src._annotated;
        _injectableValueId = src._injectableValueId;
    }
    
    @Override
    public CreatorProperty withValueDeserializer(JsonDeserializer<Object> deser) {
        return new CreatorProperty(this, deser);
    }

    /**
     * Method that can be called to locate value to be injected for this
     * property, if it is configured for this.
     * 
     * @since 1.9
     */
    public Object findInjectableValue(DeserializationContext context, Object beanInstance)
    {
        if (_injectableValueId == null) {
            throw new IllegalStateException("Property '"+getName()
                    +"' (type "+getClass().getName()+") has no injectable value id configured");
        }
        return context.findInjectableValue(_injectableValueId, this, beanInstance);
    }
    
    /**
     * Method to find value to inject, and inject it to this property.
     * 
     * @since 1.9
     */
    public void inject(DeserializationContext context, Object beanInstance)
        throws IOException
    {
        set(beanInstance, findInjectableValue(context, beanInstance));
    }
    
    /*
    /**********************************************************
    /* BeanProperty impl
    /**********************************************************
     */
    
    @Override
    public <A extends Annotation> A getAnnotation(Class<A> acls) {
        if (_annotated == null) {
            return null;
        }
        return _annotated.getAnnotation(acls);
    }

    @Override public AnnotatedMember getMember() {  return _annotated; }
    
    /*
    /**********************************************************
    /* Overridden methods
    /**********************************************************
     */

    @Override
    public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
                                  Object instance)
        throws IOException, JsonProcessingException
    {
        set(instance, deserialize(jp, ctxt));
    }

    @Override
    public void set(Object instance, Object value)
        throws IOException
    {
        /* Hmmmh. Should we return quietly (NOP), or error?
         * For now, let's just bail out without fuss.
         */
        //throw new IllegalStateException("Method should never be called on a "+getClass().getName());
    }

    @Override
    public Object getInjectableValueId() {
        return _injectableValueId;
    }
}
