/*
 *  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 java.io;

import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Comparator;

import org.apache.harmony.misc.accessors.ObjectAccessor;

/**
 * Describes a field for the purpose of serialization. Classes can define the
 * collection of fields that are serialized, which may be different from the set
 * of all declared fields.
 * 
 * @see ObjectOutputStream#writeFields()
 * @see ObjectInputStream#readFields()
 */
public class ObjectStreamField implements Comparable<Object> {

    static final int FIELD_IS_NOT_RESOLVED = -1;
    static final int FIELD_IS_ABSENT = -2;

    // Declared name of the field
    private String name;

    // Declared type of the field
    private Object type;

    // offset of this field in the object
    int offset;

    // Cached version of intern'ed type String
    private String typeString;

    private boolean unshared;

    private boolean isDeserialized;

    private long assocFieldID = FIELD_IS_NOT_RESOLVED;

    long getFieldID(ObjectAccessor accessor, Class<?> declaringClass) {
        if (assocFieldID != FIELD_IS_NOT_RESOLVED) {
            return assocFieldID;
        } else {
            try {  
                assocFieldID = accessor.getFieldID(declaringClass, name);
            } catch(NoSuchFieldError e) {
                assocFieldID = FIELD_IS_ABSENT;
            }
            return assocFieldID;
        }
    }

    /**
     * Constructs an ObjectStreamField with the specified name and type.
     * 
     * @param name
     *            the name of the field.
     * @param cl
     *            the type of the field.
     * @throws NullPointerException
     *             if {@code name} or {@code cl} is {@code null}.
     */
    public ObjectStreamField(String name, Class<?> cl) {
        if (name == null || cl == null) {
            throw new NullPointerException();
        }
        this.name = name;
        this.type = new WeakReference<Class<?>>(cl);
    }

    /**
     * Constructs an ObjectStreamField with the specified name, type and the
     * indication if it is unshared.
     * 
     * @param name
     *            the name of the field.
     * @param cl
     *            the type of the field.
     * @param unshared
     *            {@code true} if the field is written and read unshared;
     *            {@code false} otherwise.
     * @throws NullPointerException
     *             if {@code name} or {@code cl} is {@code null}.
     * @see ObjectOutputStream#writeUnshared(Object)
     */
    public ObjectStreamField(String name, Class<?> cl, boolean unshared) {
        if (name == null || cl == null) {
            throw new NullPointerException();
        }
        this.name = name;
        this.type = (cl.getClassLoader() == null) ? cl
                : new WeakReference<Class<?>>(cl);
        this.unshared = unshared;
    }

    /**
     * Constructs an ObjectStreamField with the given name and the given type.
     * The type may be null.
     * 
     * @param signature
     *            A String representing the type of the field
     * @param name
     *            a String, the name of the field, or null
     */
    ObjectStreamField(String signature, String name) {
        if (name == null) {
            throw new NullPointerException();
        }
        this.name = name;
        this.typeString = signature.replace('.', '/').intern();
        this.isDeserialized = true;
    }

    /**
     * Compares this field descriptor to the specified one. Checks first if one
     * of the compared fields has a primitive type and the other one not. If so,
     * the field with the primitive type is considered to be "smaller". If both
     * fields are equal, their names are compared.
     * 
     * @param o
     *            the object to compare with.
     * @return -1 if this field is "smaller" than field {@code o}, 0 if both
     *         fields are equal; 1 if this field is "greater" than field {@code
     *         o}.
     */
    public int compareTo(Object o) {
        ObjectStreamField f = (ObjectStreamField) o;
        boolean thisPrimitive = this.isPrimitive();
        boolean fPrimitive = f.isPrimitive();

        // If one is primitive and the other isn't, we have enough info to
        // compare
        if (thisPrimitive != fPrimitive) {
            return thisPrimitive ? -1 : 1;
        }

        // Either both primitives or both not primitives. Compare based on name.
        return this.getName().compareTo(f.getName());
    }

    @Override
    public boolean equals(Object arg0) {
        return (arg0 instanceof ObjectStreamField) && (compareTo(arg0) == 0);
    }

    @Override
    public int hashCode() {
        return getName().hashCode();
    }

    /**
     * Gets the name of this field.
     * 
     * @return the field's name.
     */
    public String getName() {
        return name;
    }

    /**
     * Gets the offset of this field in the object.
     * 
     * @return this field's offset.
     */
    public int getOffset() {
        return offset;
    }

    /**
     * Return the type of the field the receiver represents, this is an internal
     * method
     * 
     * @return A Class object representing the type of the field
     */
    private Class<?> getTypeInternal() {
        if (type instanceof WeakReference) {
            return (Class<?>) ((WeakReference<?>) type).get();
        }
        return (Class<?>) type;
    }

    /**
     * Gets the type of this field.
     * 
     * @return a {@code Class} object representing the type of the field.
     */
    public Class<?> getType() {
        Class<?> cl = getTypeInternal();
        if (isDeserialized && !cl.isPrimitive()) {
            return Object.class;
        }
        return cl;
    }

    /**
     * Gets a character code for the type of this field. The following codes are
     * used:
     * 
     * <pre>
     * B     byte
     * C     char
     * D     double
     * F     float
     * I     int
     * J     long
     * L     class or interface
     * S     short
     * Z     boolean
     * [     array
     * </pre>
     *
     * @return the field's type code.
     */
    public char getTypeCode() {
        Class<?> t = getTypeInternal();
        if (t == Integer.TYPE) {
            return 'I';
        }
        if (t == Byte.TYPE) {
            return 'B';
        }
        if (t == Character.TYPE) {
            return 'C';
        }
        if (t == Short.TYPE) {
            return 'S';
        }
        if (t == Boolean.TYPE) {
            return 'Z';
        }
        if (t == Long.TYPE) {
            return 'J';
        }
        if (t == Float.TYPE) {
            return 'F';
        }
        if (t == Double.TYPE) {
            return 'D';
        }
        if (t.isArray()) {
            return '[';
        }
        return 'L';
    }

    /**
     * Gets the type signature used by the VM to represent the type of this
     * field.
     * 
     * @return the signature of this field's class or {@code null} if this
     *         field's type is primitive.
     */
    public String getTypeString() {
        if (isPrimitive()) {
            return null;
        }
        if (typeString == null) {
            Class<?> t = getTypeInternal();
            String typeName = t.getName().replace('.', '/');
            String str = (t.isArray()) ? typeName : ("L" + typeName + ';'); //$NON-NLS-1$
            typeString = str.intern();
        }
        return typeString;
    }

    /**
     * Indicates whether this field's type is a primitive type.
     * 
     * @return {@code true} if this field's type is primitive; {@code false} if
     *         the type of this field is a regular class.
     */
    public boolean isPrimitive() {
        Class<?> t = getTypeInternal();
        return t != null && t.isPrimitive();
    }

    /**
     * Sets this field's offset in the object.
     * 
     * @param newValue
     *            the field's new offset.
     */
    protected void setOffset(int newValue) {
        this.offset = newValue;
    }

    /**
     * Returns a string containing a concise, human-readable description of this
     * field descriptor.
     * 
     * @return a printable representation of this descriptor.
     */
    @Override
    public String toString() {
        return this.getClass().getName() + '(' + getName() + ':'
                + getTypeInternal() + ')';
    }

    /**
     * Sorts the fields for dumping. Primitive types come first, then regular
     * types.
     * 
     * @param fields
     *            ObjectStreamField[] fields to be sorted
     */
    static void sortFields(ObjectStreamField[] fields) {
        // Sort if necessary
        if (fields.length > 1) {
            Comparator<ObjectStreamField> fieldDescComparator = new Comparator<ObjectStreamField>() {
                public int compare(ObjectStreamField f1, ObjectStreamField f2) {
                    return f1.compareTo(f2);
                }
            };
            Arrays.sort(fields, fieldDescComparator);
        }
    }

    void resolve(ClassLoader loader) {
        if (typeString.length() == 1) {
            switch (typeString.charAt(0)) {
                case 'I':
                    type = Integer.TYPE;
                    return;
                case 'B':
                    type = Byte.TYPE;
                    return;
                case 'C':
                    type = Character.TYPE;
                    return;
                case 'S':
                    type = Short.TYPE;
                    return;
                case 'Z':
                    type = Boolean.TYPE;
                    return;
                case 'J':
                    type = Long.TYPE;
                    return;
                case 'F':
                    type = Float.TYPE;
                    return;
                case 'D':
                    type = Double.TYPE;
                    return;
            }
        }
        String className = typeString.replace('/', '.');
        if (className.charAt(0) == 'L') {
            // remove L and ;
            className = className.substring(1, className.length() - 1);
        }
        try {
            Class<?> cl = Class.forName(className, false, loader);
            type = (cl.getClassLoader() == null) ? cl
                    : new WeakReference<Class<?>>(cl);
        } catch (ClassNotFoundException e) {
            // Ignored
        }
    }

    /**
     * Indicats whether this field is unshared.
     * 
     * @return {@code true} if this field is unshared, {@code false} otherwise.
     */
    public boolean isUnshared() {
        return unshared;
    }
    
    void setUnshared(boolean unshared) {
        this.unshared = unshared;
    }
}
