package org.codehaus.jackson.map.type;

import java.lang.reflect.Array;

import org.codehaus.jackson.type.JavaType;

/**
 * Array types represent Java arrays, both primitive and object valued.
 * Further, Object-valued arrays can have element type of any other
 * legal {@link JavaType}.
 */
public final class ArrayType
    extends TypeBase
{
    /**
     * Type of elements in the array.
     */
    protected final JavaType _componentType;

    /**
     * We will also keep track of shareable instance of empty array,
     * since it usually needs to be constructed any way; and because
     * it is essentially immutable and thus can be shared.
     */
    protected final Object _emptyArray;

    private ArrayType(JavaType componentType, Object emptyInstance,
            Object valueHandler, Object typeHandler)
    {
        super(emptyInstance.getClass(), componentType.hashCode(),
                valueHandler, typeHandler);
        _componentType = componentType;
        _emptyArray = emptyInstance;
    }

    /**
     * @deprecated Since 1.9, if you must directly instantiate,
     *  call method that takes handlers
     */
    @Deprecated
    public static ArrayType construct(JavaType componentType)
    {
        return construct(componentType, null, null);
    }                                   

    public static ArrayType construct(JavaType componentType,
            Object valueHandler, Object typeHandler)
    {
        /* This is bit messy: there is apparently no other way to
         * reconstruct actual concrete/raw array class from component
         * type, than to construct an instance, get class (same is
         * true for GenericArracyType as well; hence we won't bother
         * passing that in).
         */
        Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0);
        return new ArrayType(componentType, emptyInstance, null, null);
    }                                   
    
    // Since 1.7:
    @Override
    public ArrayType withTypeHandler(Object h)
    {
        if (h == _typeHandler) {
            return this;
        }
        return new ArrayType(_componentType, _emptyArray, _valueHandler, h);
    }

    // Since 1.7:
    @Override
    public ArrayType withContentTypeHandler(Object h)
    {
        if (h == _componentType.getTypeHandler()) {
            return this;
        }
        return new ArrayType(_componentType.withTypeHandler(h), _emptyArray,
                _valueHandler, _typeHandler);
    }

    // Since 1.9:
    @Override
    public ArrayType withValueHandler(Object h) {
        if (h == _valueHandler) {
            return this;
        }
        return new ArrayType(_componentType, _emptyArray, h, _typeHandler);
    }

    // Since 1.9:
    @Override
    public ArrayType withContentValueHandler(Object h) {
        if (h == _componentType.getValueHandler()) {
            return this;
        }
        return new ArrayType(_componentType.withValueHandler(h), _emptyArray,
                _valueHandler, _typeHandler);
    }
    
    @Override
    protected String buildCanonicalName() {
        return _class.getName();
    }
    
    /*
    /**********************************************************
    /* Methods for narrowing conversions
    /**********************************************************
     */

    /**
     * Handling of narrowing conversions for arrays is trickier: for now,
     * it is not even allowed.
     */
    @Override
    protected JavaType _narrow(Class<?> subclass)
    {
        /* Ok: need a bit of indirection here. First, must replace component
         * type (and check that it is compatible), then re-construct.
         */
        if (!subclass.isArray()) { // sanity check, should never occur
            throw new IllegalArgumentException("Incompatible narrowing operation: trying to narrow "+toString()+" to class "+subclass.getName());
        }
        /* Hmmh. This is an awkward back reference... but seems like the
         * only simple way to do it.
         */
        Class<?> newCompClass = subclass.getComponentType();
        /* 14-Mar-2011, tatu: it gets even worse, as we do not have access to
         *   currently configured TypeFactory. This could theoretically cause
         *   problems (when narrowing from array of Objects, to array of non-standard
         *   Maps, for example); but for now need to defer solving this until
         *   it actually becomes a real problem, not just potential one.
         *   (famous last words?)
         */
        JavaType newCompType = TypeFactory.defaultInstance().constructType(newCompClass);
        return construct(newCompType, _valueHandler, _typeHandler);
    }

    /**
     * For array types, both main type and content type can be modified;
     * but ultimately they are interchangeable.
     */
    @Override
    public JavaType narrowContentsBy(Class<?> contentClass)
    {
        // Can do a quick check first:
        if (contentClass == _componentType.getRawClass()) {
            return this;
        }
        return construct(_componentType.narrowBy(contentClass),
                _valueHandler, _typeHandler);
    }

    @Override
    public JavaType widenContentsBy(Class<?> contentClass)
    {
        // Can do a quick check first:
        if (contentClass == _componentType.getRawClass()) {
            return this;
        }
        return construct(_componentType.widenBy(contentClass),
                _valueHandler, _typeHandler);
    }
    
    /*
    /**********************************************************
    /* Overridden methods
    /**********************************************************
     */

    @Override
    public boolean isArrayType() { return true; }
    
    /**
     * For some odd reason, modifiers for array classes would
     * claim they are abstract types. Not so, at least for our
     * purposes.
     */
    @Override
    public boolean isAbstract() { return false; }

    /**
     * For some odd reason, modifiers for array classes would
     * claim they are abstract types. Not so, at least for our
     * purposes.
     */
    @Override
    public boolean isConcrete() { return true; }

    @Override
    public boolean hasGenericTypes() {
        // arrays are not parameterized, but element type may be:
        return _componentType.hasGenericTypes();
    }
    
    /**
     * Not sure what symbolic name is used internally, if any;
     * let's follow naming of Collection types here.
     * Should not really matter since array types have no
     * super types.
     */
    @Override
    public String containedTypeName(int index) {
        if (index == 0) return "E";
        return null;
    }
    
    /*
    /**********************************************************
    /* Public API
    /**********************************************************
     */

    @Override
    public boolean isContainerType() { return true; }

    @Override
    public JavaType getContentType() { return  _componentType; }

    @Override
    public int containedTypeCount() { return 1; }
    @Override
    public JavaType containedType(int index) {
            return (index == 0) ? _componentType : null;
    }
    
    @Override
    public StringBuilder getGenericSignature(StringBuilder sb) {
        sb.append('[');
        return _componentType.getGenericSignature(sb);
    }

    @Override
    public StringBuilder getErasedSignature(StringBuilder sb) {
        sb.append('[');
        return _componentType.getErasedSignature(sb);
    }
    
    /*
    /**********************************************************
    /* Standard methods
    /**********************************************************
     */

    @Override
    public String toString()
    {
        return "[array type, component type: "+_componentType+"]";
    }

    @Override
    public boolean equals(Object o)
    {
        if (o == this) return true;
        if (o == null) return false;
        if (o.getClass() != getClass()) return false;

        ArrayType other = (ArrayType) o;
        return _componentType.equals(other._componentType);
    }
}
