/*
 * 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.commons.beanutils2;


import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * <p>Minimal implementation of the {@code DynaBean} interface.  Can be
 * used as a convenience base class for more sophisticated implementations.</p>
 *
 * <p><strong>IMPLEMENTATION NOTE</strong> - Instances of this class that are
 * accessed from multiple threads simultaneously need to be synchronized.</p>
 *
 * <p><strong>IMPLEMENTATION NOTE</strong> - Instances of this class can be
 * successfully serialized and deserialized <strong>ONLY</strong> if all
 * property values are {@code Serializable}.</p>
 *
 */

public class BasicDynaBean implements DynaBean, Serializable {

    private static final long serialVersionUID = 1L;



    /**
     * Construct a new {@code DynaBean} associated with the specified
     * {@code DynaClass} instance.
     *
     * @param dynaClass The DynaClass we are associated with
     */
    public BasicDynaBean(final DynaClass dynaClass) {

        super();
        this.dynaClass = dynaClass;

    }





    /**
     * The {@code DynaClass} "base class" that this DynaBean
     * is associated with.
     */
    protected DynaClass dynaClass = null;


    /**
     * The set of property values for this DynaBean, keyed by property name.
     */
    protected HashMap<String, Object> values = new HashMap<>();

    /** Map decorator for this DynaBean */
    private transient Map<String, Object> mapDecorator;

    /**
     * <p>
     * Return a Map representation of this DynaBean.
     * <p>
     * This, for example, could be used in JSTL in the following way to access
     * a DynaBean's {@code fooProperty}:
     * <ul><li>{@code ${myDynaBean.<b>map</b>.fooProperty}}</li></ul>
     *
     * @return a Map representation of this DynaBean
     * @since 1.8.0
     */
    public Map<String, Object> getMap() {

        // cache the Map
        if (mapDecorator == null) {
            mapDecorator = new DynaBeanPropertyMapDecorator(this);
        }
        return mapDecorator;

    }




    /**
     * Does the specified mapped property contain a value for the specified
     * key value?
     *
     * @param name Name of the property to check
     * @param key Name of the key to check
     * @return {@code true} if the mapped property contains a value for
     * the specified key, otherwise {@code false}
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     */
    @Override
    public boolean contains(final String name, final String key) {

        final Object value = values.get(name);
        if (value == null) {
            throw new NullPointerException
                    ("No mapped value for '" + name + "(" + key + ")'");
        } else if (value instanceof Map) {
            return ((Map<?, ?>) value).containsKey(key);
        } else {
            throw new IllegalArgumentException
                    ("Non-mapped property for '" + name + "(" + key + ")'");
        }

    }


    /**
     * Return the value of a simple property with the specified name.
     *
     * @param name Name of the property whose value is to be retrieved
     * @return The property's value
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     */
    @Override
    public Object get(final String name) {

        // Return any non-null value for the specified property
        final Object value = values.get(name);
        if (value != null) {
            return value;
        }

        // Return a null value for a non-primitive property
        final Class<?> type = getDynaProperty(name).getType();
        if (!type.isPrimitive()) {
            return value;
        }

        // Manufacture default values for primitive properties
        if (type == Boolean.TYPE) {
            return Boolean.FALSE;
        } else if (type == Byte.TYPE) {
            return Byte.valueOf((byte) 0);
        } else if (type == Character.TYPE) {
            return Character.valueOf((char) 0);
        } else if (type == Double.TYPE) {
            return Double.valueOf(0.0);
        } else if (type == Float.TYPE) {
            return Float.valueOf((float) 0.0);
        } else if (type == Integer.TYPE) {
            return Integer.valueOf(0);
        } else if (type == Long.TYPE) {
            return Long.valueOf(0);
        } else if (type == Short.TYPE) {
            return Short.valueOf((short) 0);
        } else {
            return null;
        }

    }


    /**
     * Return the value of an indexed property with the specified name.
     *
     * @param name Name of the property whose value is to be retrieved
     * @param index Index of the value to be retrieved
     * @return The indexed property's value
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not indexed
     * @throws IndexOutOfBoundsException if the specified index
     *  is outside the range of the underlying property
     * @throws NullPointerException if no array or List has been
     *  initialized for this property
     */
    @Override
    public Object get(final String name, final int index) {

        final Object value = values.get(name);
        if (value == null) {
            throw new NullPointerException
                    ("No indexed value for '" + name + "[" + index + "]'");
        } else if (value.getClass().isArray()) {
            return Array.get(value, index);
        } else if (value instanceof List) {
            return ((List<?>) value).get(index);
        } else {
            throw new IllegalArgumentException
                    ("Non-indexed property for '" + name + "[" + index + "]'");
        }

    }


    /**
     * Return the value of a mapped property with the specified name,
     * or {@code null} if there is no value for the specified key.
     *
     * @param name Name of the property whose value is to be retrieved
     * @param key Key of the value to be retrieved
     * @return The mapped property's value
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not mapped
     */
    @Override
    public Object get(final String name, final String key) {

        final Object value = values.get(name);
        if (value == null) {
            throw new NullPointerException
                    ("No mapped value for '" + name + "(" + key + ")'");
        } else if (value instanceof Map) {
            return ((Map<?, ?>) value).get(key);
        } else {
            throw new IllegalArgumentException
                    ("Non-mapped property for '" + name + "(" + key + ")'");
        }

    }


    /**
     * Return the {@code DynaClass} instance that describes the set of
     * properties available for this DynaBean.
     *
     * @return The associated DynaClass
     */
    @Override
    public DynaClass getDynaClass() {

        return this.dynaClass;

    }


    /**
     * Remove any existing value for the specified key on the
     * specified mapped property.
     *
     * @param name Name of the property for which a value is to
     *  be removed
     * @param key Key of the value to be removed
     *
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     */
    @Override
    public void remove(final String name, final String key) {

        final Object value = values.get(name);
        if (value == null) {
            throw new NullPointerException
                    ("No mapped value for '" + name + "(" + key + ")'");
        } else if (value instanceof Map) {
            ((Map<?, ?>) value).remove(key);
        } else {
            throw new IllegalArgumentException
                    ("Non-mapped property for '" + name + "(" + key + ")'");
        }

    }


    /**
     * Set the value of a simple property with the specified name.
     *
     * @param name Name of the property whose value is to be set
     * @param value Value to which this property is to be set
     *
     * @throws ConversionException if the specified value cannot be
     *  converted to the type required for this property
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws NullPointerException if an attempt is made to set a
     *  primitive property to null
     */
    @Override
    public void set(final String name, final Object value) {

        final DynaProperty descriptor = getDynaProperty(name);
        if (value == null) {
            if (descriptor.getType().isPrimitive()) {
                throw new NullPointerException
                        ("Primitive value for '" + name + "'");
            }
        } else if (!isAssignable(descriptor.getType(), value.getClass())) {
            throw new ConversionException
                    ("Cannot assign value of type '" +
                    value.getClass().getName() +
                    "' to property '" + name + "' of type '" +
                    descriptor.getType().getName() + "'");
        }
        values.put(name, value);

    }


    /**
     * Set the value of an indexed property with the specified name.
     *
     * @param name Name of the property whose value is to be set
     * @param index Index of the property to be set
     * @param value Value to which this property is to be set
     *
     * @throws ConversionException if the specified value cannot be
     *  converted to the type required for this property
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not indexed
     * @throws IndexOutOfBoundsException if the specified index
     *  is outside the range of the underlying property
     */
    @Override
    public void set(final String name, final int index, final Object value) {

        final Object prop = values.get(name);
        if (prop == null) {
            throw new NullPointerException
                    ("No indexed value for '" + name + "[" + index + "]'");
        } else if (prop.getClass().isArray()) {
            Array.set(prop, index, value);
        } else if (prop instanceof List) {
            try {
                @SuppressWarnings("unchecked")
                final
                // This is safe to cast because list properties are always
                // of type Object
                List<Object> list = (List<Object>) prop;
                list.set(index, value);
            } catch (final ClassCastException e) {
                throw new ConversionException(e.getMessage());
            }
        } else {
            throw new IllegalArgumentException
                    ("Non-indexed property for '" + name + "[" + index + "]'");
        }

    }


    /**
     * Set the value of a mapped property with the specified name.
     *
     * @param name Name of the property whose value is to be set
     * @param key Key of the property to be set
     * @param value Value to which this property is to be set
     *
     * @throws ConversionException if the specified value cannot be
     *  converted to the type required for this property
     * @throws IllegalArgumentException if there is no property
     *  of the specified name
     * @throws IllegalArgumentException if the specified property
     *  exists, but is not mapped
     */
    @Override
    public void set(final String name, final String key, final Object value) {

        final Object prop = values.get(name);
        if (prop == null) {
            throw new NullPointerException
                    ("No mapped value for '" + name + "(" + key + ")'");
        } else if (prop instanceof Map) {
            @SuppressWarnings("unchecked")
            final
            // This is safe to cast because mapped properties are always
            // maps of types String -> Object
            Map<String, Object> map = (Map<String, Object>) prop;
            map.put(key, value);
        } else {
            throw new IllegalArgumentException
                    ("Non-mapped property for '" + name + "(" + key + ")'");
        }

    }





    /**
     * Return the property descriptor for the specified property name.
     *
     * @param name Name of the property for which to retrieve the descriptor
     * @return The property descriptor
     *
     * @throws IllegalArgumentException if this is not a valid property
     *  name for our DynaClass
     */
    protected DynaProperty getDynaProperty(final String name) {

        final DynaProperty descriptor = getDynaClass().getDynaProperty(name);
        if (descriptor == null) {
            throw new IllegalArgumentException
                    ("Invalid property name '" + name + "'");
        }
        return descriptor;

    }


    /**
     * Is an object of the source class assignable to the destination class?
     *
     * @param dest Destination class
     * @param source Source class
     * @return {@code true} if the source class is assignable to the
     * destination class, otherwise {@code false}
     */
    protected boolean isAssignable(final Class<?> dest, final Class<?> source) {

        if (dest.isAssignableFrom(source) ||
                dest == Boolean.TYPE && source == Boolean.class ||
                dest == Byte.TYPE && source == Byte.class ||
                dest == Character.TYPE && source == Character.class ||
                dest == Double.TYPE && source == Double.class ||
                dest == Float.TYPE && source == Float.class ||
                dest == Integer.TYPE && source == Integer.class ||
                dest == Long.TYPE && source == Long.class ||
                dest == Short.TYPE && source == Short.class) {
            return true;
        }
        return false;

    }


}
