/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.harmony.lang.annotation;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.annotation.AnnotationTypeMismatchException;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * This class represents member element of an annotation. 
 * It consists of name and value, supplemented with element
 * definition information (such as declared type of element). 
 * <br>The value may be one of the following types:
 * <ul>
 * <li> boxed primitive
 * <li> Class
 * <li> enum constant
 * <li> annotation (nested)
 * <li> one-dimensional array of the above 
 * <li> Throwable 
 * </ul>
 * The last type is specific for this implementation; a Throwable value
 * means that the error occured during parsing or resolution of corresponding
 * class-data structures and throwing is delayed until the element
 * is requested for value. 
 * 
 * @see android.lang.annotation.AnnotationFactory
 * 
 * @author Alexey V. Varlamov, Serguei S. Zapreyev
 * @version $Revision$
 */
@SuppressWarnings({"serial"})
public class AnnotationMember implements Serializable {
    
    /**
     * Tag description of a Throwable value type.
     */
    protected static final char ERROR = '!';

    /**
     * Tag description of an array value type.
     */
    protected static final char ARRAY = '[';
    
    /**
     * Tag description of all value types except arrays and Throwables.
     */
    protected static final char OTHER = '*';
    
//    public static final char INT = 'I';
//    public static final char CHAR = 'C';
//    public static final char DOUBLE = 'D';
//    public static final char FLOAT = 'F';
//    public static final char BYTE = 'B';
//    public static final char LONG = 'J';
//    public static final char SHORT = 'S';
//    public static final char BOOL = 'Z';
//    public static final char CLASS = 'c';
//    public static final char ENUM = 'e';
//    public static final char ANTN = '@';

    private enum DefaultValues {NO_VALUE}
    
    /**
     * Singleton representing missing element value.
     */
    protected static final Object NO_VALUE = DefaultValues.NO_VALUE;

    protected final String name;
    protected final Object value; // a primitive value is wrapped to the corresponding wrapper class
    protected final char tag; 
    // no sense to serialize definition info as it can be changed arbitrarily
    protected transient Class<?> elementType; 
    protected transient Method definingMethod;
    
    
    /**
     * Creates a new element with specified name and value.
     * Definition info will be provided later when this 
     * element becomes actual annotation member.
     * @param name element name, must not be null
     * @param val element value, should be of addmissible type, 
     * as specified in the description of this class
     * 
     * @see #setDefinition(AnnotationMember)
     */
    public AnnotationMember(String name, Object val) {
        this.name = name;
        value = val == null ? NO_VALUE : val;
        if (value instanceof Throwable) {
            tag = ERROR;
        } else if (value.getClass().isArray()) {
            tag = ARRAY;
        } else {
            tag = OTHER;
        }
    }
    
    /**
     * Creates the completely defined element.
     * @param name element name, must not be null
     * @param value element value, should be of addmissible type, 
     * as specified in the description of this class
     * @param m element-defining method, reflected on the annotation type
     * @param type declared type of this element 
     * (return type of the defining method)
     */
    public AnnotationMember(String name, Object val, Class type, Method m) {
        this(name, val);
        
        definingMethod = m;
        
        if (type == int.class) {
            elementType = Integer.class;
        } else if (type == boolean.class) {
            elementType = Boolean.class;
        } else if (type == char.class) {
            elementType = Character.class;
        } else if (type == float.class) {
            elementType = Float.class;
        } else if (type == double.class) {
            elementType = Double.class;
        } else if (type == long.class) {
            elementType = Long.class;
        } else if (type == short.class) {
            elementType = Short.class;
        } else if (type == byte.class) {
            elementType = Byte.class;
        } else {
            elementType = type;
        }
    }
    
    /**
     * Fills in element's definition info and returns this.
     */
    protected AnnotationMember setDefinition(AnnotationMember copy) {
        definingMethod = copy.definingMethod;
        elementType = copy.elementType;
        return this;
    }
    
    /**
     * Returns readable description of this annotation value. 
     */
    public String toString() {
        if (tag == ARRAY) {
            StringBuilder sb = new StringBuilder(80);
            sb.append(name).append("=[");
            int len = Array.getLength(value);
            for (int i = 0; i < len; i++) {
                if (i != 0) sb.append(", ");
                sb.append(Array.get(value, i));
            }
            return sb.append("]").toString();
        } else {
            return name+ "=" +value;
        }
    }
    
    /**
     * Returns true if the specified object represents equal element
     * (equivalent name-value pair). 
     * <br> A special case is the contained Throwable value; it is considered 
     * transcendent so no other element would be equal.
     * @return true if passed object is equivalent element representation,
     * false otherwise 
     * @see #equalArrayValue(Object)
     * @see java.lang.annotation.Annotation#equals(Object)
     */
    public boolean equals(Object obj) {
        if (obj == this) {
            // not a mere optimization, 
            // this is needed for consistency with hashCode()
            return true;
        }
        if (obj instanceof AnnotationMember) {
            AnnotationMember that = (AnnotationMember)obj;
            if (name.equals(that.name) && tag == that.tag) {
                if (tag == ARRAY) {
                    return equalArrayValue(that.value);
                } else if (tag == ERROR) {
                    // undefined value is incomparable (transcendent)
                    return false;
                } else {
                    return value.equals(that.value);
                }
            }
        }
        return false;
    }
    
    /**
     * Returns true if the contained value and a passed object are equal arrays,
     * false otherwise. Appropriate overloaded method of Arrays.equals() 
     * is used for equality testing. 
     * @see java.util.Arrays#equals(java.lang.Object[], java.lang.Object[])
     * @return true if the value is array and is equal to specified object,
     * false otherwise
     */
    public boolean equalArrayValue(Object otherValue) {
        if (value instanceof Object[] && otherValue instanceof Object[]) {
            return Arrays.equals((Object[])value, (Object[])otherValue);
        }
        Class type = value.getClass();
        if (type != otherValue.getClass()) {
            return false;
        }
        if (type == int[].class) {
            return Arrays.equals((int[])value, (int[])otherValue);
        } else if (type == byte[].class) {
            return Arrays.equals((byte[])value, (byte[])otherValue);
        } else if (type == short[].class) {
            return Arrays.equals((short[])value, (short[])otherValue);
        } else if (type == long[].class) {
            return Arrays.equals((long[])value, (long[])otherValue);
        } else if (type == char[].class) {
            return Arrays.equals((char[])value, (char[])otherValue);
        } else if (type == boolean[].class) {
            return Arrays.equals((boolean[])value, (boolean[])otherValue);
        } else if (type == float[].class) {
            return Arrays.equals((float[])value, (float[])otherValue);
        } else if (type == double[].class) {
            return Arrays.equals((double[])value, (double[])otherValue);
        }
        return false;
    }
    
    /**
     * Computes hash code of this element. The formula is as follows:
     * <code> (name.hashCode() * 127) ^ value.hashCode() </code>
     * <br>If value is an array, one of overloaded Arrays.hashCode()
     * methods is used.
     * @return the hash code
     * @see java.util.Arrays#hashCode(java.lang.Object[])
     * @see java.lang.annotation.Annotation#hashCode()
     */
    public int hashCode() {
        int hash = name.hashCode() * 127;
        if (tag == ARRAY) {
            Class type = value.getClass();
            if (type == int[].class) {
                return hash ^ Arrays.hashCode((int[])value);
            } else if (type == byte[].class) {
                return hash ^ Arrays.hashCode((byte[])value);
            } else if (type == short[].class) {
                return hash ^ Arrays.hashCode((short[])value);
            } else if (type == long[].class) {
                return hash ^ Arrays.hashCode((long[])value);
            } else if (type == char[].class) {
                return hash ^ Arrays.hashCode((char[])value);
            } else if (type == boolean[].class) {
                return hash ^ Arrays.hashCode((boolean[])value);
            } else if (type == float[].class) {
                return hash ^ Arrays.hashCode((float[])value);
            } else if (type == double[].class) {
                return hash ^ Arrays.hashCode((double[])value);
            }
            return hash ^ Arrays.hashCode((Object[])value);
        } else {
            return hash ^ value.hashCode();
        }
    }
    
    /**
     * Throws contained error (if any) with a renewed stack trace.
     */
    public void rethrowError() throws Throwable {
        if (tag == ERROR) {
            // need to throw cloned exception for thread safety
            // besides it is better to provide actual stack trace
            // rather than recorded during parsing
            
            // first check for expected types 
            if (value instanceof TypeNotPresentException) {
                TypeNotPresentException tnpe = (TypeNotPresentException)value;
                throw new TypeNotPresentException(tnpe.typeName(), tnpe.getCause());
            } else if (value instanceof EnumConstantNotPresentException) {
                EnumConstantNotPresentException ecnpe = (EnumConstantNotPresentException)value;
                throw new EnumConstantNotPresentException(ecnpe.enumType(), ecnpe.constantName());
            } else if (value instanceof ArrayStoreException) {
                ArrayStoreException ase = (ArrayStoreException)value;
                throw new ArrayStoreException(ase.getMessage());
            }
            // got some other error, have to go with deep cloning
            // via serialization mechanism
            Throwable error = (Throwable)value;
            StackTraceElement[] ste = error.getStackTrace();
            ByteArrayOutputStream bos = new ByteArrayOutputStream(
                    ste == null ? 512 : (ste.length + 1) * 80);
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(error);
            oos.flush();
            oos.close();
            ByteArrayInputStream bis = new ByteArrayInputStream(bos
                    .toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            error = (Throwable)ois.readObject();
            ois.close();
            
            throw error;
        }
    }
    
    /**
     * Validates contained value against its member definition
     * and if ok returns the value.
     * Otherwise, if the value type mismatches definition 
     * or the value itself describes an error, 
     * throws appropriate exception.
     * <br> Note, this method may return null if this element was constructed 
     * with such value.  
     * 
     * @see #rethrowError()
     * @see #copyValue()
     * @return actual valid value or null if no value
     */
    public Object validateValue() throws Throwable {
        if (tag == ERROR) {
            rethrowError();
        } 
        if (value == NO_VALUE) {
            return null;
        }
        if (elementType == value.getClass() 
                || elementType.isInstance(value)) { // nested annotation value
            return copyValue();
        } else {
            throw new AnnotationTypeMismatchException(definingMethod, 
                    value.getClass().getName());
        }

    }        

    
    /**
     * Provides mutation-safe access to contained value. That is, caller is free 
     * to modify the returned value, it will not affect the contained data value.
     * @return cloned value if it is mutable or the original immutable value
     */
    public Object copyValue() throws Throwable
    {
        if (tag != ARRAY || Array.getLength(value) == 0) {
            return value;
        }
        Class type = value.getClass();
        if (type == int[].class) {
            return ((int[])value).clone();
        } else if (type == byte[].class) {
            return ((byte[])value).clone();
        } else if (type == short[].class) {
            return ((short[])value).clone();
        } else if (type == long[].class) {
            return ((long[])value).clone();
        } else if (type == char[].class) {
            return ((char[])value).clone();
        } else if (type == boolean[].class) {
            return ((boolean[])value).clone();
        } else if (type == float[].class) {
            return ((float[])value).clone();
        } else if (type == double[].class) {
            return ((double[])value).clone();
        }
        return ((Object[])value).clone();
    }
}
