/**
 * Copyright 2009-2013 Oy Vaadin Ltd
 *
 * Licensed 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.eclipse.osbp.dsl.dto.lib.services.jpa.metadata;

import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * An extended version of {@link PropertyMetadata} that provides additional
 * information about persistent properties.
 * 
 * @author Petter Holmström (Vaadin Ltd)
 * @since 1.0
 */
public class PersistentPropertyMetadata extends PropertyMetadata {

    private static final long serialVersionUID = -4097189601179456814L;

    /**
     * Enumeration defining the property access types.
     * 
     * @author Petter Holmström (Vaadin Ltd)
     */
    public enum AccessType {

        /**
         * The property is accessed as a JavaBean property using getters and
         * setters.
         */
        METHOD,
        /**
         * The property is accessed directly as a field.
         */
        FIELD
    }

    private final PropertyKind propertyKind;
    private final ClassMetadata<?> typeMetadata;
    transient final Field field;
    // Required for serialization
    protected final String fieldName;
    protected final Class<?> fieldDeclaringClass;

    /**
     * Creates a new instance of <code>PersistentPropertyMetadata</code>.
     * 
     * @param name
     *            the name of the property (must not be null).
     * @param type
     *            the type of the property (must not be null).
     * @param propertyKind
     *            the kind of the property, must be either
     *            {@link PropertyKind#ONE_TO_MANY},
     *            {@link PropertyKind#MANY_TO_MANY},
     *            {@link PropertyKind#ELEMENT_COLLECTION} or
     *            {@link PropertyKind#SIMPLE} .
     * @param field
     *            the field that can be used to access the property (must not be
     *            null).
     */
    PersistentPropertyMetadata(String name, Class<?> type,
            PropertyKind propertyKind, Field field, Method setter) {
        super(name, type, null, setter);
        assert propertyKind == PropertyKind.ONE_TO_MANY
                || propertyKind == PropertyKind.MANY_TO_MANY
                || propertyKind == PropertyKind.ELEMENT_COLLECTION
                || propertyKind == PropertyKind.SIMPLE : "propertyKind must be ONE_TO_MANY or SIMPLE";
        assert field != null : "field must not be null";
        this.propertyKind = propertyKind;
        typeMetadata = null;
        this.field = field;
        fieldName = field.getName();
        fieldDeclaringClass = field.getDeclaringClass();
    }

    /**
     * Creates a new instance of <code>PersistentPropertyMetadata</code>.
     * 
     * @param name
     *            the name of the property (must not be null).
     * @param type
     *            type type of the property (must not be null).
     * @param propertyKind
     *            the kind of the property, must be either
     *            {@link PropertyKind#ONE_TO_MANY},
     *            {@link PropertyKind#MANY_TO_MANY},
     *            {@link PropertyKind#ELEMENT_COLLECTION} or
     *            {@link PropertyKind#SIMPLE} .
     * @param getter
     *            the getter method that can be used to read the property value
     *            (must not be null).
     * @param setter
     *            the setter method that can be used to set the property value
     *            (must not be null).
     */
    PersistentPropertyMetadata(String name, Class<?> type,
            PropertyKind propertyKind, Method getter, Method setter) {
        super(name, type, getter, setter);
        assert propertyKind == PropertyKind.ONE_TO_MANY
                || propertyKind == PropertyKind.MANY_TO_MANY
                || propertyKind == PropertyKind.ELEMENT_COLLECTION
                || propertyKind == PropertyKind.SIMPLE : "propertyKind must be ONE_TO_MANY or SIMPLE";
        assert getter != null : "getter must not be null";
        assert setter != null : "setter must not be null";
        this.propertyKind = propertyKind;
        typeMetadata = null;
        field = null;
        fieldName = null;
        fieldDeclaringClass = null;
    }

    /**
     * Creates a new instance of <code>PersistentPropertyMetadata</code>.
     * 
     * @param name
     *            the name of the property (must not be null).
     * @param type
     *            the type metadata of the property (must not be null).
     * @param propertyKind
     *            the kind of the property, must be either
     *            {@link PropertyKind#MANY_TO_ONE},
     *            {@link PropertyKind#ONE_TO_ONE} or
     *            {@link PropertyKind#EMBEDDED}.
     * @param field
     *            the field that can be used to access the property (must not be
     *            null).
     */
    PersistentPropertyMetadata(String name, ClassMetadata<?> type,
            PropertyKind propertyKind, Field field, Method setter) {
        super(name, type.getMappedClass(), null, setter);
        assert type != null : "type must not be null";
        assert propertyKind == PropertyKind.MANY_TO_ONE
                || propertyKind == PropertyKind.ONE_TO_ONE
                || propertyKind == PropertyKind.EMBEDDED : "propertyKind must be MANY_TO_ONE or EMBEDDED";
        assert field != null : "field must not be null";
        this.propertyKind = propertyKind;
        typeMetadata = type;
        this.field = field;
        fieldName = field.getName();
        fieldDeclaringClass = field.getDeclaringClass();
    }

    /**
     * Creates a new instance of <code>PersistentPropertyMetadata</code>.
     * 
     * @param name
     *            the name of the property (must not be null).
     * @param type
     *            the type metadata of the property (must not be null).
     * @param propertyKind
     *            the kind of the property, must be either
     *            {@link PropertyKind#MANY_TO_ONE},
     *            {@link PropertyKind#ONE_TO_ONE} or
     *            {@link PropertyKind#EMBEDDED}.
     * @param getter
     *            the getter method that can be used to read the property value
     *            (must not be null).
     * @param setter
     *            the setter method that can be used to set the property value
     *            (must not be null).
     */
    PersistentPropertyMetadata(String name, ClassMetadata<?> type,
            PropertyKind propertyKind, Method getter, Method setter) {
        super(name, type.getMappedClass(), getter, setter);
        assert type != null : "type must not be null";
        assert propertyKind == PropertyKind.MANY_TO_ONE
                || propertyKind == PropertyKind.ONE_TO_ONE
                || propertyKind == PropertyKind.EMBEDDED : "propertyKind must be MANY_TO_ONE or EMBEDDED";
        assert getter != null : "getter must not be null";
        assert setter != null : "setter must not be null";
        this.propertyKind = propertyKind;
        typeMetadata = type;
        field = null;
        fieldName = null;
        fieldDeclaringClass = null;
    }

    /**
     * This constructor is used when deserializing the object.
     * 
     * @see #readResolve()
     */
    private PersistentPropertyMetadata(String name,
            ClassMetadata<?> typeMetadata, Class<?> type,
            PropertyKind propertyKind, Method getter, Method setter, Field field) {
        super(name, type, getter, setter);
        this.propertyKind = propertyKind;
        this.typeMetadata = typeMetadata;
        this.field = field;
        if (this.field == null) {
            fieldName = null;
            fieldDeclaringClass = null;
        } else {
            fieldName = field.getName();
            fieldDeclaringClass = field.getDeclaringClass();
        }
    }

    /**
     * The metadata of the property type, if it is embedded or a reference.
     * Otherwise, this method returns null.
     * 
     * @see #getPropertyKind()
     */
    public ClassMetadata<?> getTypeMetadata() {
        return typeMetadata;
    }

    /**
     * The kind of the property.
     */
    @Override
    public PropertyKind getPropertyKind() {
        return propertyKind;
    }

    /**
     * The way the property value is accessed (as a JavaBean property or as a
     * field).
     */
    public AccessType getAccessType() {
        return field != null ? AccessType.FIELD : AccessType.METHOD;
    }

    @Override
    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
        if (field != null) {
            return field.getAnnotation(annotationClass);
        } else {
            return super.getAnnotation(annotationClass);
        }
    }

    @Override
    public Annotation[] getAnnotations() {
        if (field != null) {
            return field.getAnnotations();
        } else {
            return super.getAnnotations();
        }
    }

    @Override
    public Object readResolve() throws ObjectStreamException {
        try {
            Field f = null;
            if (fieldName != null) {
                f = fieldDeclaringClass.getDeclaredField(fieldName);
            }
            Method getterM = null;
            if (getterName != null) {
                getterM = getterDeclaringClass.getDeclaredMethod(getterName);
            }
            Method setterM = null;
            if (setterName != null) {
                // use the type from field if possible. type is Vaadin property
                // type, which means that for primitive types we convert it to
                // wrapper type
                Class<?> setterType = (f == null) ? getType() : f.getType();
                setterM = setterDeclaringClass.getDeclaredMethod(setterName,
                        setterType);
            }
            return new PersistentPropertyMetadata(getName(), typeMetadata,
                    getType(), propertyKind, getterM, setterM, f);
        } catch (Exception e) {
            e.printStackTrace();
            throw new InvalidObjectException(e.getMessage());
        }
    }

    /**
     * Persistent properties are always writable.
     * <p>
     * {@inheritDoc }.
     */
    @Override
    public boolean isWritable() {
        return true; // field != null || super.isWritable();
    }

    /*
     * Note, that we only compare the mapped classes of the typeMetadata fields.
     * If we compared the typeMetadata fields themselves, we could run into an
     * infinite loop if there are circular references (e.g. a parent-property of
     * the same type) in the metadata.
     */

    @Override
    public boolean equals(Object obj) {
        if (super.equals(obj)) { // Includes check of parameter type
            PersistentPropertyMetadata other = (PersistentPropertyMetadata) obj;
            return ( other != null && propertyKind.equals(other.propertyKind) )
                    && (typeMetadata == null ? other.typeMetadata == null
                            : typeMetadata.getMappedClass().equals(
                                    other.typeMetadata.getMappedClass()))
                    && (field == null ? other.field == null : field
                            .equals(other.field));
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = super.hashCode();
        hash = hash * 31 + propertyKind.hashCode();
        if (typeMetadata != null) {
            hash = hash * 31 + typeMetadata.getMappedClass().hashCode();
        }
        if (field != null) {
            hash = hash * 31 + field.hashCode();
        }
        return hash;
    }
}
