/*
 * 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 freemarker.template;

import java.io.Serializable;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import freemarker.core._DelayedJQuote;
import freemarker.core._TemplateModelException;
import freemarker.ext.beans.BeansWrapper;

/**
 * A simple implementation of the {@link TemplateHashModelEx} interface, using its own underlying {@link Map} or
 * {@link SortedMap} for storing the hash entries. If you are wrapping an already existing {@link Map}, you should
 * certainly use {@link DefaultMapAdapter} instead (see comparison below).
 *
 * <p>
 * This class is thread-safe if you don't call modifying methods (like {@link #put(String, Object)},
 * {@link #remove(String)}, etc.) after you have made the object available for multiple threads (assuming you have
 * published it safely to the other threads; see JSR-133 Java Memory Model). These methods aren't called by FreeMarker,
 * so it's usually not a concern.
 * 
 * <p>
 * <b>{@link SimpleHash} VS {@link DefaultMapAdapter} - Which to use when?</b>
 * 
 * <p>
 * For a {@link Map} that exists regardless of FreeMarker, only you need to access it from templates,
 * {@link DefaultMapAdapter} should be the default choice, as it reflects the exact behavior of the underlying
 * {@link Map} (no surprises), can be unwrapped to the originally wrapped object (important when passing it to Java
 * methods from the template), and has more predictable performance (no spikes).
 * 
 * <p>
 * For a hash that's made specifically to be used from templates, creating an empty {@link SimpleHash} then filling it
 * with {@link SimpleHash#put(String, Object)} is usually the way to go, as the resulting hash is significantly faster
 * to read from templates than a {@link DefaultMapAdapter} (though it's somewhat slower to read from a plain Java method
 * to which it had to be passed adapted to a {@link Map}).
 * 
 * <p>
 * It also matters if for how many times will the <em>same</em> {@link Map} entry be read from the template(s) later, on
 * average. If, on average, you read each entry for more than 4 times, {@link SimpleHash} will be most certainly faster,
 * but if for 2 times or less (and especially if not at all) then {@link DefaultMapAdapter} will be faster. Before 
 * choosing based on performance though, pay attention to the behavioral differences; {@link SimpleHash} will 
 * shallow-copy the original {@link Map} at construction time, so key order will be lost in some cases, and it won't 
 * reflect {@link Map} content changes after the {@link SimpleHash} construction, also {@link SimpleHash} can't be 
 * unwrapped to the original {@link Map} instance.
 *
 * @see DefaultMapAdapter
 * @see TemplateHashModelEx
 */
public class SimpleHash extends WrappingTemplateModel implements TemplateHashModelEx2, Serializable {

    private final Map map;
    private boolean putFailed;
    private Map unwrappedMap;

    /**
     * Constructs an empty hash that uses the default wrapper set in
     * {@link WrappingTemplateModel#setDefaultObjectWrapper(ObjectWrapper)}.
     * 
     * @deprecated Use {@link #SimpleHash(ObjectWrapper)}
     */
    @Deprecated
    public SimpleHash() {
        this((ObjectWrapper) null);
    }

    /**
     * Creates a new simple hash with the copy of the underlying map and the
     * default wrapper set in 
     * {@link WrappingTemplateModel#setDefaultObjectWrapper(ObjectWrapper)}.
     * @param map The Map to use for the key/value pairs. It makes a copy for 
     * internal use. If the map implements the {@link SortedMap} interface, the
     * internal copy will be a {@link TreeMap}, otherwise it will be a 
     * {@link HashMap}.
     * 
     * @deprecated Use {@link #SimpleHash(Map, ObjectWrapper)}
     */
    @Deprecated
    public SimpleHash(Map map) {
        this(map, null);
    }

    /**
     * Creates an empty simple hash using the specified object wrapper.
     * @param wrapper The object wrapper to use to wrap objects into
     * {@link TemplateModel} instances. If null, the default wrapper set in 
     * {@link WrappingTemplateModel#setDefaultObjectWrapper(ObjectWrapper)} is
     * used.
     */
    public SimpleHash(ObjectWrapper wrapper) {
        super(wrapper);
        map = new HashMap();
    }

    /**
     * Creates an instance that will use the specified {@link Map} directly as its backing store; beware, the
     * {@link Map} will be possibly modified by {@link SimpleHash}, even if you only read the {@link SimpleHash}.
     * That's because when a value is read, it's replaced with the corresponding {@link TemplateModel}.
     *
     * <p>The goal of this constructor is to allow you to control technical aspects, like the initial capacity, and
     * ordering of the underlying {@link Map} implementation. The iteration order of the {@link SimpleHash} will be
     * the same as of the underlying {@link Map}.
     *
     * @param directMap The map that the instance will use directly as backing storage; possibly will be modified,
     *                  even when you only read the {@link SimpleHash}! Must allow any kind of object as value,
     *                  including {@code null}! Supporting {@code null} keys is not needed.
     *
     * @param overloadDistinction To avoid ambiguity with other overloads; the value is unused.
     *
     * @since 2.3.30
     */
    public SimpleHash(Map<String, Object> directMap, ObjectWrapper wrapper, int overloadDistinction) {
        super(wrapper);
        this.map = directMap;
    }

    /**
     * Creates a new hash by shallow-coping (possibly cloning) the underlying map; in many applications you should use
     * {@link DefaultMapAdapter} instead.
     *
     * @param map
     *            The Map to use for the key/value pairs. It makes a copy for internal use. If the map implements the
     *            {@link SortedMap} interface, the internal copy will be a {@link TreeMap}, otherwise it will be a
     * @param wrapper
     *            The object wrapper to use to wrap contained objects into {@link TemplateModel} instances. Using
     *            {@code null} is deprecated but allowed, in which case the deprecated default wrapper set in
     *            {@link WrappingTemplateModel#setDefaultObjectWrapper(ObjectWrapper)} is used.
     */
    public SimpleHash(Map map, ObjectWrapper wrapper) {
        super(wrapper);
        Map mapCopy;
        try {
            mapCopy = copyMap(map);
        } catch (ConcurrentModificationException cme) {
            //This will occur extremely rarely.
            //If it does, we just wait 5 ms and try again. If 
            // the ConcurrentModificationException
            // is thrown again, we just let it bubble up this time.
            // TODO: Maybe we should log here.
            try {
                Thread.sleep(5);
            } catch (InterruptedException ie) {
            }
            synchronized (map) {
                mapCopy = copyMap(map);
            }
        }
        this.map = mapCopy;
    }

    protected Map copyMap(Map map) {
        if (map instanceof HashMap) {
            return (Map) ((HashMap) map).clone();
        }
        if (map instanceof SortedMap) {
            if (map instanceof TreeMap) {
                return (Map) ((TreeMap) map).clone();
            } else {
                return new TreeMap((SortedMap) map);
            }
        } 
        return new HashMap(map);
    }

    /**
     * Adds a key-value entry to this hash.
     *
     * @param key
     *            The name by which the object is identified in the template.
     * @param value
     *            The value to which the name will be associated. This will only be wrapped to {@link TemplateModel}
     *            lazily when it's first read.
     */
    public void put(String key, Object value) {
        map.put(key, value);
        unwrappedMap = null;
    }

    /**
     * Puts a boolean in the map
     *
     * @param key the name by which the resulting {@code TemplateModel}
     * is identified in the template.
     * @param b the boolean to store.
     */
    public void put(String key, boolean b) {
        put(key, b ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE);
    }

    @Override
    public TemplateModel get(String key) throws TemplateModelException {
        Object result;
        try {
            result = map.get(key);
        } catch (ClassCastException e) {
            throw new _TemplateModelException(e,
                    "ClassCastException while getting Map entry with String key ",
                    new _DelayedJQuote(key));
        } catch (NullPointerException e) {
            throw new _TemplateModelException(e,
                    "NullPointerException while getting Map entry with String key ",
                    new _DelayedJQuote(key));
        }
        // The key to use for putting -- it's the key that already exists in
        // the map (either key or charKey below). This way, we'll never put a 
        // new key in the map, avoiding spurious ConcurrentModificationException
        // from another thread iterating over the map, see bug #1939742 in 
        // SourceForge tracker.
        Object putKey = null;
        if (result == null) {
            // Check for Character key if this is a single-character string.
            // In SortedMap-s, however, we can't do that safely, as it can cause ClassCastException.
            if (key.length() == 1 && !(map instanceof SortedMap)) {
                Character charKey = Character.valueOf(key.charAt(0));
                try {
                    result = map.get(charKey);
                    if (result != null || map.containsKey(charKey)) {
                        putKey = charKey;
                    }
                } catch (ClassCastException e) {
                    throw new _TemplateModelException(e,
                            "ClassCastException while getting Map entry with Character key ",
                            new _DelayedJQuote(key));
                } catch (NullPointerException e) {
                    throw new _TemplateModelException(e,
                            "NullPointerException while getting Map entry with Character key ",
                            new _DelayedJQuote(key));
                }
            }
            if (putKey == null) {
                if (!map.containsKey(key)) {
                    return null;
                } else {
                    putKey = key;
                }
            }
        } else {
            putKey = key;
        }
        
        if (result instanceof TemplateModel) {
            return (TemplateModel) result;
        }
        
        TemplateModel tm = wrap(result);
        if (!putFailed) {
            try {
                map.put(putKey, tm);
            } catch (Exception e) {
                // If it's immutable or something, we just keep going.
                putFailed = true;
            }
        }
        return tm;
    }

    /**
     * Tells if the map contains a key or not, regardless if the associated value is {@code null} or not.
     * @since 2.3.20
     */
    public boolean containsKey(String key) {
        return map.containsKey(key);
    }

    /**
     * Removes the given key from the underlying map.
     *
     * @param key the key to be removed
     */
    public void remove(String key) {
        map.remove(key);
    }

    /**
     * Adds all the key/value entries in the map
     * @param m the map with the entries to add, the keys are assumed to be strings.
     */

    public void putAll(Map m) {
        for (Iterator it = m.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            this.put((String) entry.getKey(), entry.getValue());
        }
    }
    
    /**
     * Note that this method creates and returns a deep-copy of the underlying hash used
     * internally. This could be a gotcha for some people
     * at some point who want to alter something in the data model,
     * but we should maintain our immutability semantics (at least using default SimpleXXX wrappers) 
     * for the data model. It will recursively unwrap the stuff in the underlying container. 
     */
    public Map toMap() throws TemplateModelException {
        if (unwrappedMap == null) {
            Class mapClass = this.map.getClass();
            Map m = null;
            try {
                m = (Map) mapClass.newInstance();
            } catch (Exception e) {
                throw new TemplateModelException("Error instantiating map of type " + mapClass.getName() + "\n" + e.getMessage());
            }
            // Create a copy to maintain immutability semantics and
            // Do nested unwrapping of elements if necessary.
            BeansWrapper bw = BeansWrapper.getDefaultInstance();
            for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
                Map.Entry entry = (Map.Entry) it.next();
                Object key = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof TemplateModel) {
                    value = bw.unwrap((TemplateModel) value);
                }
                m.put(key, value);
            }
            unwrappedMap = m;
        }
        return unwrappedMap;
    }

    /**
     * Returns the {@code toString()} of the underlying {@link Map}.
     */
    @Override
    public String toString() {
        return map.toString();
    }

    @Override
    public int size() {
        return map.size();
    }

    @Override
    public boolean isEmpty() {
        return map == null || map.isEmpty();
    }

    @Override
    public TemplateCollectionModel keys() {
        return new SimpleCollection(map.keySet(), getObjectWrapper());
    }

    @Override
    public TemplateCollectionModel values() {
        return new SimpleCollection(map.values(), getObjectWrapper());
    }

    @Override
    public KeyValuePairIterator keyValuePairIterator() {
        return new MapKeyValuePairIterator(map, getObjectWrapper());
    }

    public SimpleHash synchronizedWrapper() {
        return new SynchronizedHash();
    }
    
    private class SynchronizedHash extends SimpleHash {

        @Override
        public boolean isEmpty() {
            synchronized (SimpleHash.this) {
                return SimpleHash.this.isEmpty();
            }
        }
        
        @Override
        public void put(String key, Object obj) {
            synchronized (SimpleHash.this) {
                SimpleHash.this.put(key, obj);
            }
        }

        @Override
        public TemplateModel get(String key) throws TemplateModelException {
            synchronized (SimpleHash.this) {
                return SimpleHash.this.get(key);
            }
        }

        @Override
        public void remove(String key) {
            synchronized (SimpleHash.this) {
                SimpleHash.this.remove(key);
            }
        }

        @Override
        public int size() {
            synchronized (SimpleHash.this) {
                return SimpleHash.this.size();
            }
        }

        @Override
        public TemplateCollectionModel keys() {
            synchronized (SimpleHash.this) {
                return SimpleHash.this.keys();
            }
        }

        @Override
        public TemplateCollectionModel values() {
            synchronized (SimpleHash.this) {
                return SimpleHash.this.values();
            }
        }

        @Override
        public KeyValuePairIterator keyValuePairIterator() {
            synchronized (SimpleHash.this) {
                return SimpleHash.this.keyValuePairIterator();
            }
        }
        
        @Override
        public Map toMap() throws TemplateModelException {
            synchronized (SimpleHash.this) {
                return SimpleHash.this.toMap();
            }
        }
    
    }
}
