/*
 * 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.util.Map;

/**
 * <p>Provides a <i>light weight</i> {@code DynaBean</code> facade to a <code>Map}
 *  with <i>lazy</i> map/list processing.</p>
 *
 * <p>Its a <i>light weight</i> {@code DynaBean} implementation because there is no
 *    actual {@code DynaClass</code> associated with this <code>DynaBean} - in fact
 *    it implements the {@code DynaClass} interface itself providing <i>pseudo</i> DynaClass
 *    behavior from the actual values stored in the {@code Map}.</p>
 *
 * <p>As well providing rhe standard {@code DynaBean</code> access to the <code>Map}'s properties
 *    this class also provides the usual <i>Lazy</i> behavior:</p>
 *    <ul>
 *       <li>Properties don't need to be pre-defined in a {@code DynaClass}</li>
 *       <li>Indexed properties ({@code Lists</code> or <code>Arrays}) are automatically instantiated
 *           and <i>grown</i> so that they are large enough to cater for the index being set.</li>
 *       <li>Mapped properties are automatically instantiated.</li>
 *    </ul>
 *
 * <p><b><u><i>Restricted</i> DynaClass</u></b></p>
 *    <p>This class implements the {@code MutableDynaClass} interface.
 *       {@code MutableDynaClass</code> have a facility to <i>restrict</i> the <code>DynaClass}
 *       so that its properties cannot be modified. If the {@code MutableDynaClass} is
 *       restricted then calling any of the {@code set()} methods for a property which
 *       doesn't exist will result in a {@code IllegalArgumentException} being thrown.</p>
 *
 */
public class LazyDynaMap extends LazyDynaBean implements MutableDynaClass {

    private static final long serialVersionUID = 1L;

    /**
     * The name of this DynaClass (analogous to the
     * {@code getName()</code> method of <code>java.lang.Class}).
     */
    protected String name;

    /**
     * Controls whether changes to this DynaClass's properties are allowed.
     */
    protected boolean restricted;

    /**
     * <p>Controls whether the {@code getDynaProperty()} method returns
     * null if a property doesn't exist - or creates a new one.</p>
     *
     * <p>Default is {@code false}.
     */
    protected boolean returnNull = false;


    

    /**
     * Default Constructor.
     */
    public LazyDynaMap() {
        this(null, (Map<String, Object>)null);
    }

    /**
     * Construct a new {@code LazyDynaMap} with the specified name.
     *
     * @param name Name of this DynaBean class
     */
    public LazyDynaMap(final String name) {
        this(name, (Map<String, Object>)null);
    }

    /**
     * Construct a new {@code LazyDynaMap</code> with the specified <code>Map}.
     *
     * @param values The Map backing this {@code LazyDynaMap}
     */
    public LazyDynaMap(final Map<String, Object> values) {
        this(null, values);
    }

    /**
     * Construct a new {@code LazyDynaMap</code> with the specified name and  <code>Map}.
     *
     * @param name Name of this DynaBean class
     * @param values The Map backing this {@code LazyDynaMap}
     */
    public LazyDynaMap(final String name, final Map<String, Object> values) {
        this.name      = name   == null ? "LazyDynaMap" : name;
        this.values    = values == null ? newMap()      : values;
        this.dynaClass = this;
    }

    /**
     * Construct a new {@code LazyDynaMap} with the specified properties.
     *
     * @param properties Property descriptors for the supported properties
     */
    public LazyDynaMap(final DynaProperty[] properties) {
        this(null, properties);
    }

    /**
     * Construct a new {@code LazyDynaMap} with the specified name and properties.
     *
     * @param name Name of this DynaBean class
     * @param properties Property descriptors for the supported properties
     */
    public LazyDynaMap(final String name, final DynaProperty[] properties) {
        this(name, (Map<String, Object>)null);
        if (properties != null) {
            for (final DynaProperty propertie : properties) {
                add(propertie);
            }
        }
    }

    /**
     * Construct a new {@code LazyDynaMap} based on an exisiting DynaClass
     *
     * @param dynaClass DynaClass to copy the name and properties from
     */
    public LazyDynaMap(final DynaClass dynaClass) {
        this(dynaClass.getName(), dynaClass.getDynaProperties());
    }

    

    /**
     * Set the Map backing this {@code DynaBean}
     *
     * @param values The new Map of values
     */
    public void setMap(final Map<String, Object> values) {
        this.values = values;
    }

    /**
     * Return the underlying Map backing this {@code DynaBean}
     * @return the underlying Map
     * @since 1.8.0
     */
    @Override
    public Map<String, Object> getMap() {
        return values;
    }

    

    /**
     * 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
     */
    @Override
    public void set(final String name, final Object value) {

        if (isRestricted() && !values.containsKey(name)) {
            throw new IllegalArgumentException
                    ("Invalid property name '" + name + "' (DynaClass is restricted)");
        }

        values.put(name, value);

    }

    

    /**
     * Return the name of this DynaClass (analogous to the
     * {@code getName()</code> method of <code>java.lang.Class})
     *
     * @return the name of the DynaClass
     */
    @Override
    public String getName() {
        return this.name;
    }

    /**
     * <p>Return a property descriptor for the specified property.</p>
     *
     * <p>If the property is not found and the {@code returnNull} indicator is
     *    {@code true</code>, this method always returns <code>null}.</p>
     *
     * <p>If the property is not found and the {@code returnNull} indicator is
     *    {@code false} a new property descriptor is created and returned (although
     *    its not actually added to the DynaClass's properties). This is the default
     *    behavior.</p>
     *
     * <p>The reason for not returning a {@code null} property descriptor is that
     *    {@code BeanUtils} uses this method to check if a property exists
     *    before trying to set it - since these <i>Map</i> implementations automatically
     *    add any new properties when they are set, returning {@code null} from
     *    this method would defeat their purpose.</p>
     *
     * @param name Name of the dynamic property for which a descriptor
     *  is requested
     * @return The descriptor for the specified property
     *
     * @throws IllegalArgumentException if no property name is specified
     */
    @Override
    public DynaProperty getDynaProperty(final String name) {

        if (name == null) {
            throw new IllegalArgumentException("Property name is missing.");
        }

        // If it doesn't exist and returnNull is false
        // create a new DynaProperty
        if (!values.containsKey(name) && isReturnNull()) {
            return null;
        }

        final Object value = values.get(name);

        if (value == null) {
            return new DynaProperty(name);
        }
        return new DynaProperty(name, value.getClass());

    }

    /**
     * <p>Return an array of {@code ProperyDescriptors} for the properties
     * currently defined in this DynaClass.  If no properties are defined, a
     * zero-length array will be returned.</p>
     *
     * <p><strong>FIXME</strong> - Should we really be implementing
     * {@code getBeanInfo()} instead, which returns property descriptors
     * and a bunch of other stuff?</p>
     * @return the set of properties for this DynaClass
     */
    @Override
    public DynaProperty[] getDynaProperties() {

        int i = 0;
        final DynaProperty[] properties = new DynaProperty[values.size()];
        for (final Map.Entry<String, Object> e : values.entrySet()) {
            final String name = e.getKey();
            final Object value = values.get(name);
            properties[i++] = new DynaProperty(name, value == null ? null
                    : value.getClass());
        }

        return properties;

    }

    /**
     * Instantiate and return a new DynaBean instance, associated
     * with this DynaClass.
     * @return A new {@code DynaBean} instance
     */
    @Override
    public DynaBean newInstance()  {

        // Create a new instance of the Map
        Map<String, Object> newMap = null;
        try {
            final
            // The new map is used as properties map
            Map<String, Object> temp = getMap().getClass().newInstance();
            newMap = temp;
        } catch(final Exception ex) {
            newMap = newMap();
        }

        // Crate new LazyDynaMap and initialize properties
        final LazyDynaMap lazyMap = new LazyDynaMap(newMap);
        final DynaProperty[] properties = this.getDynaProperties();
        if (properties != null) {
            for (final DynaProperty propertie : properties) {
                lazyMap.add(propertie);
            }
        }
        return lazyMap;
    }


    

    /**
     * <p>Is this DynaClass currently restricted.</p>
     * <p>If restricted, no changes to the existing registration of
     *  property names, data types, readability, or writeability are allowed.</p>
     *
     * @return {@code true} if this Mutable {@link DynaClass} is restricted,
     * otherwise {@code false}
     */
    @Override
    public boolean isRestricted() {
        return restricted;
    }

    /**
     * <p>Set whether this DynaClass is currently restricted.</p>
     * <p>If restricted, no changes to the existing registration of
     *  property names, data types, readability, or writeability are allowed.</p>
     *
     * @param restricted The new restricted state
     */
    @Override
    public void setRestricted(final boolean restricted) {
        this.restricted = restricted;
    }

    /**
     * Add a new dynamic property with no restrictions on data type,
     * readability, or writeability.
     *
     * @param name Name of the new dynamic property
     *
     * @throws IllegalArgumentException if name is null
     */
    @Override
    public void add(final String name) {
        add(name, null);
    }

    /**
     * Add a new dynamic property with the specified data type, but with
     * no restrictions on readability or writeability.
     *
     * @param name Name of the new dynamic property
     * @param type Data type of the new dynamic property (null for no
     *  restrictions)
     *
     * @throws IllegalArgumentException if name is null
     * @throws IllegalStateException if this DynaClass is currently
     *  restricted, so no new properties can be added
     */
    @Override
    public void add(final String name, final Class<?> type) {

        if (name == null) {
            throw new IllegalArgumentException("Property name is missing.");
        }

        if (isRestricted()) {
            throw new IllegalStateException("DynaClass is currently restricted. No new properties can be added.");
        }

        final Object value = values.get(name);

        // Check if the property already exists
        if (value == null) {
            values.put(name, type == null ? null : createProperty(name, type));
        }

    }

    /**
     * <p>Add a new dynamic property with the specified data type, readability,
     * and writeability.</p>
     *
     * <p><strong>N.B.</strong>Support for readable/writeable properties has not been implemented
     *    and this method always throws a {@code UnsupportedOperationException}.</p>
     *
     * <p>I'm not sure the intention of the original authors for this method, but it seems to
     *    me that readable/writable should be attributes of the {@code DynaProperty} class
     *    (which they are not) and is the reason this method has not been implemented.</p>
     *
     * @param name Name of the new dynamic property
     * @param type Data type of the new dynamic property (null for no
     *  restrictions)
     * @param readable Set to {@code true} if this property value
     *  should be readable
     * @param writeable Set to {@code true} if this property value
     *  should be writeable
     *
     * @throws UnsupportedOperationException anytime this method is called
     */
    @Override
    public void add(final String name, final Class<?> type, final boolean readable, final boolean writeable) {
        throw new java.lang.UnsupportedOperationException("readable/writable properties not supported");
    }

    /**
     * Add a new dynamic property.
     *
     * @param property Property the new dynamic property to add.
     *
     * @throws IllegalArgumentException if name is null
     */
    protected void add(final DynaProperty property) {
        add(property.getName(), property.getType());
    }

    /**
     * Remove the specified dynamic property, and any associated data type,
     * readability, and writeability, from this dynamic class.
     * <strong>NOTE</strong> - This does <strong>NOT</strong> cause any
     * corresponding property values to be removed from DynaBean instances
     * associated with this DynaClass.
     *
     * @param name Name of the dynamic property to remove
     *
     * @throws IllegalArgumentException if name is null
     * @throws IllegalStateException if this DynaClass is currently
     *  restricted, so no properties can be removed
     */
    @Override
    public void remove(final String name) {

        if (name == null) {
            throw new IllegalArgumentException("Property name is missing.");
        }

        if (isRestricted()) {
            throw new IllegalStateException("DynaClass is currently restricted. No properties can be removed.");
        }

        // Remove, if property doesn't exist
        if (values.containsKey(name)) {
            values.remove(name);
        }

    }


    

    /**
     * Should this DynaClass return a {@code null} from
     * the {@code getDynaProperty(name)} method if the property
     * doesn't exist.
     *
     * @return {@code true</code> if a <code>null} {@link DynaProperty}
     * should be returned if the property doesn't exist, otherwise
     * {@code false} if a new {@link DynaProperty} should be created.
     */
    public boolean isReturnNull() {
        return returnNull;
    }

    /**
     * Set whether this DynaClass should return a {@code null} from
     * the {@code getDynaProperty(name)} method if the property
     * doesn't exist.
     *
     * @param returnNull {@code true</code> if a <code>null} {@link DynaProperty}
     * should be returned if the property doesn't exist, otherwise
     * {@code false} if a new {@link DynaProperty} should be created.
     */
    public void setReturnNull(final boolean returnNull) {
        this.returnNull = returnNull;
    }


    

   /**
     * <p>Indicate whether a property actually exists.</p>
     *
     * <p><strong>N.B.</strong> Using {@code getDynaProperty(name) == null}
     * doesn't work in this implementation because that method might
     * return a DynaProperty if it doesn't exist (depending on the
     * {@code returnNull} indicator).</p>
     *
     * @param name Name of the dynamic property
     * @return {@code true} if the property exists,
     * otherwise {@code false}
     * @throws IllegalArgumentException if no property name is specified
     */
    @Override
    protected boolean isDynaProperty(final String name) {

        if (name == null) {
            throw new IllegalArgumentException("Property name is missing.");
        }

        return values.containsKey(name);

    }

}