/*
 * 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.sis.feature;

import java.util.Map;
import java.util.HashMap;
import org.opengis.util.ScopedName;
import org.opengis.util.GenericName;
import org.apache.sis.internal.util.AbstractMap;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.collection.WeakValueHashMap;
import org.apache.sis.util.resources.Errors;

import static org.apache.sis.util.ArgumentChecks.ensureNonNullElement;

// Branch-dependent imports
import org.opengis.feature.AttributeType;


/**
 * Implementation of the map returned by {@link DefaultAttributeType#characteristics()}.
 * Information provided by this implementation are also used by {@link CharacteristicMap}.
 *
 * <h2>Comparison with standard hash map</h2>
 * The straightforward approach would be to store the attributes directly as values in a standard {@code HashMap}.
 * But instead of that, we store attributes in an array and the array indices in a {@code HashMap}. This level of
 * indirection is useless if we consider only the {@link DefaultAttributeType#characteristics()} method, since a
 * standard {@code HashMap<String,AttributeType>} would work as well or better. However this level of indirection
 * become useful for {@link CharacteristicMap} (the map returned by {@link AbstractAttribute#characteristics()}),
 * since it allows a more efficient storage. We do this effort because some applications may create a very large
 * amount of attribute instances.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 * @since   0.5
 * @module
 */
final class CharacteristicTypeMap extends AbstractMap<String,AttributeType<?>> {
    /**
     * For sharing the same {@code CharacteristicTypeMap} instances among the attribute types
     * having the same characteristics.
     */
    @SuppressWarnings("unchecked")
    private static final WeakValueHashMap<AttributeType<?>[],CharacteristicTypeMap> SHARED =
            new WeakValueHashMap<>((Class) AttributeType[].class);

    /*
     * This class has intentionally no reference to the AttributeType for which we are providing characteristics.
     * This allows us to use the same CharacteristicTypeMap instance for various attribute types having the same
     * characteristic (e.g. many measurements may have an "accuracy" characteristic).
     */

    /**
     * Characteristics of an other attribute type (the {@code source} attribute given to the constructor).
     * This array shall not be modified.
     */
    final AttributeType<?>[] characterizedBy;

    /**
     * The names of attribute types listed in the {@link #characterizedBy} array,
     * together where their index in the array. This map shall not be modified.
     */
    final Map<String,Integer> indices;

    /**
     * Creates a new map or return an existing map for the given attribute characteristics.
     *
     * <p>This method does not clone the {@code characterizedBy} array. If that array
     * is a user-provided argument, then cloning that array is caller responsibility.</p>
     *
     * @param  source           the attribute which is characterized by {@code characterizedBy}.
     * @param  characterizedBy  characteristics of {@code source}. Should not be empty.
     * @return a map for this given characteristics.
     * @throws IllegalArgumentException if two characteristics have the same name.
     */
    static CharacteristicTypeMap create(final AttributeType<?> source, final AttributeType<?>[] characterizedBy) {
        CharacteristicTypeMap map;
        synchronized (SHARED) {
            map = SHARED.get(characterizedBy);
            if (map == null) {
                map = new CharacteristicTypeMap(source, characterizedBy);
                SHARED.put(characterizedBy, map);
            }
        }
        return map;
    }

    /**
     * Creates a new map for the given attribute characteristics.
     *
     * <p>This constructor does not clone the {@code characterizedBy} array. If that array
     * is a user-provided argument, then cloning that array is caller responsibility.</p>
     *
     * @param  source           the attribute which is characterized by {@code characterizedBy}.
     * @param  characterizedBy  characteristics of {@code source}. Should not be empty.
     * @throws IllegalArgumentException if two characteristics have the same name.
     */
    private CharacteristicTypeMap(final AttributeType<?> source, final AttributeType<?>[] characterizedBy) {
        this.characterizedBy = characterizedBy;
        int index = 0;
        final Map<String,Integer> indices = new HashMap<>(Containers.hashMapCapacity(characterizedBy.length));
        final Map<String,Integer> aliases = new HashMap<>();
        for (int i=0; i<characterizedBy.length; i++) {
            final AttributeType<?> attribute = characterizedBy[i];
            ensureNonNullElement("characterizedBy", i, attribute);
            GenericName name = attribute.getName();
            String key = AbstractIdentifiedType.toString(name, source, "characterizedBy", i);
            final Integer value = index++;
            if (indices.put(key, value) != null) {
                throw new IllegalArgumentException(Errors.format(Errors.Keys.DuplicatedIdentifier_1, key));
            }
            /*
             * If some characteristics use long name of the form "head:tip", creates short aliases containing
             * only the "tip" name for convenience, provided that it does not create ambiguity. If an alias
             * could map to two or more characteristics, then that alias is not added. Those ambiguous aliases
             * are identified by the -1 value in the 'aliases' map.
             */
            while (name instanceof ScopedName) {
                if (name == (name = ((ScopedName) name).tail())) break;   // Safety against broken implementations.
                key = name.toString();
                if (key == null || (key = key.trim()).isEmpty()) break;   // Safety against broken implementations.
                if (aliases.put(key, value) != null) {
                    aliases.put(key, -1);
                }
            }
        }
        /*
         * Copy the aliases only after we finished to create the list of all fully-qualified names.
         * The copy operation shall exclude all ambiguous names.
         */
        for (final Map.Entry<String,Integer> entry : aliases.entrySet()) {
            final Integer value = entry.getValue();
            if (value >= 0) {
                indices.putIfAbsent(entry.getKey(), value);
            }
        }
        this.indices = CollectionsExt.compact(indices);
    }

    /**
     * Returns {@code true} if there is no attribute characteristics.
     */
    @Override
    public boolean isEmpty() {
        return characterizedBy.length == 0;
    }

    /**
     * Returns the number of attribute characteristics.
     */
    @Override
    public int size() {
        return characterizedBy.length;
    }

    /**
     * Returns {@code true} if this map contains an attribute characteristic of the given name.
     */
    @Override
    public boolean containsKey(final Object key) {
        return indices.containsKey(key);
    }

    /**
     * Returns {@code true} if this map contains the given attribute characteristic.
     */
    @Override
    public boolean containsValue(final Object key) {
        for (final AttributeType<?> type : characterizedBy) {
            if (type.equals(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the attribute characteristic for the given name, or {@code null} if none.
     */
    @Override
    public AttributeType<?> get(final Object key) {
        final Integer index = indices.get(key);
        return (index != null) ? characterizedBy[index] : null;
    }

    /**
     * Returns an iterator over the entries.
     * This is not the iterator returned by public API like {@code Map.entrySet().iterator()}.
     */
    @Override
    protected EntryIterator<String, AttributeType<?>> entryIterator() {
        return new EntryIterator<String, AttributeType<?>>() {
            /** Index of the next element to return in the iteration. */
            private int index;

            /** Value of current entry. */
            private AttributeType<?> value;

            /**
             * Returns {@code true} if there is more entries in the iteration.
             */
            @Override
            protected boolean next() {
                if (index < characterizedBy.length) {
                    value = characterizedBy[index++];
                    return true;
                }
                return false;
            }

            /**
             * Returns the attribute characteristic name.
             */
            @Override
            protected String getKey() {
                return value.getName().toString();
            }

            /**
             * Returns the attribute characteristic contained in this entry.
             */
            @Override
            protected AttributeType<?> getValue() {
                return value;
            }
        };
    }
}
