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

import java.util.Map;
import java.util.List;
import java.util.Arrays;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Collection;
import org.opengis.metadata.Identifier;
import org.opengis.util.TypeName;
import org.opengis.util.NameSpace;
import org.opengis.util.LocalName;
import org.opengis.util.MemberName;
import org.opengis.util.GenericName;
import org.opengis.util.NameFactory;
import org.opengis.util.InternationalString;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.collection.WeakHashSet;
import org.apache.sis.internal.util.Strings;

import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
import static org.apache.sis.util.iso.DefaultNameSpace.DEFAULT_SEPARATOR_STRING;


/**
 * A factory for creating {@link AbstractName} objects.
 * This factory provides the following methods for creating name instances:
 *
 * <ul>
 *   <li>{@link #createTypeName(NameSpace, CharSequence)}</li>
 *   <li>{@link #createMemberName(NameSpace, CharSequence, TypeName)}</li>
 *   <li>{@link #createLocalName(NameSpace, CharSequence)}</li>
 *   <li>{@link #createGenericName(NameSpace, CharSequence[])} – for local or scoped names</li>
 * </ul>
 *
 * The following methods for creating miscellaneous name-related objects:
 *
 * <ul>
 *   <li>{@link #createNameSpace(GenericName, Map)}</li>
 *   <li>{@link #createInternationalString(Map)}</li>
 * </ul>
 *
 * And the following methods for performing some analysis:
 *
 * <ul>
 *   <li>{@link #parseGenericName(NameSpace, CharSequence)}</li>
 *   <li>{@link #toGenericNames(Object)}</li>
 *   <li>{@link #toTypeName(Class)}</li>
 * </ul>
 *
 * <h2>Thread safety</h2>
 * The same {@code DefaultNameFactory} instance can be safely used by many threads without synchronization
 * on the part of the caller. Subclasses should make sure that any overridden methods remain safe to call
 * from multiple threads.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.5
 *
 * @see Names
 * @see DefaultNameSpace
 * @see DefaultScopedName
 * @see DefaultLocalName
 * @see DefaultTypeName
 * @see DefaultMemberName
 *
 * @since 0.3
 * @module
 */
public class DefaultNameFactory extends AbstractFactory implements NameFactory {
    /**
     * The key for name separator.
     */
    static final String SEPARATOR_KEY = "separator";

    /**
     * The key or the separator after the first name.
     */
    static final String HEAD_SEPARATOR_KEY = "separator.head";

    /**
     * Weak references to the name created by this factory.
     */
    private final WeakHashSet<GenericName> pool;

    /**
     * Helper class for mapping {@link Class} to {@link TypeName}, created when first needed.
     */
    private transient volatile TypeNames typeNames;

    /**
     * Creates a new factory.
     */
    public DefaultNameFactory() {
        pool = new WeakHashSet<>(GenericName.class);
    }

    /**
     * Creates an international string from a set of strings in different locales.
     *
     * @param  strings  string value for each locale key.
     * @return the international string.
     *
     * @see Types#toInternationalString(CharSequence)
     */
    @Override
    public InternationalString createInternationalString(final Map<Locale,String> strings) {
        ensureNonNull("strings", strings);
        switch (strings.size()) {
            case 0:  throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyDictionary));
            case 1:  return new SimpleInternationalString(strings.values().iterator().next());
            default: return new DefaultInternationalString(strings);
        }
        // Do not cache in the pool, because not all instances are immutable.
    }

    /**
     * Returns the value for the given key in the given properties map, or {@code null} if none.
     */
    private static String getString(final Map<String,?> properties, final String key) {
        if (properties != null) {
            final Object value = properties.get(key);
            if (value != null) {
                return value.toString();
            }
        }
        return null;
    }

    /**
     * Returns a namespace having the given name. Despite the "create" name, this method tries to
     * return an existing instance when possible. The namespace is characterized by the given name,
     * and optionally by the following properties:
     *
     * <blockquote><table class="sis">
     *   <caption>Recognized properties</caption>
     *   <tr>
     *     <th>Property name</th>
     *     <th>Purpose</th>
     *   </tr>
     *   <tr>
     *     <td>{@code "separator"}</td>
     *     <td>The separator to insert between {@linkplain AbstractName#getParsedNames() parsed names}
     *         in that namespace.</td>
     *   </tr>
     *   <tr>
     *     <td>{@code "separator.head"}</td>
     *     <td>The separator to insert between the namespace and the {@linkplain AbstractName#head() head}.<br>
     *         If omitted, then the default is the same value than {@code "separator"}.</td>
     *   </tr>
     * </table></blockquote>
     *
     * <div class="note"><b>Examples:</b>
     * <ul>
     *   <li>For URN namespace, {@code separator} = {@code ":"} is typically sufficient.</li>
     *   <li>For HTTP namespace, {@code separator.head} = {@code "://"} and {@code separator} = {@code "."}.</li>
     * </ul></div>
     *
     * @param  name  the name of the namespace to be returned. This argument can be created using
     *         <code>{@linkplain #createGenericName(NameSpace, CharSequence[]) createGenericName}(null, namespace)</code>.
     * @param  properties  an optional map of properties to be assigned to the namespace, or {@code null} if none.
     * @return a namespace having the given name and separator.
     *
     * @see Names#createLocalName(CharSequence, String, CharSequence)
     */
    @Override
    public NameSpace createNameSpace(final GenericName name, final Map<String,?> properties) {
        ensureNonNull("name", name);
        String separator = getString(properties, SEPARATOR_KEY);
        if (separator == null) {
            separator = DefaultNameSpace.DEFAULT_SEPARATOR_STRING;
        }
        String headSeparator = getString(properties, HEAD_SEPARATOR_KEY);
        if (headSeparator == null) {
            headSeparator = separator;
        }
        final boolean isEmpty = separator.isEmpty();
        if (isEmpty || headSeparator.isEmpty()) {
            throw new IllegalArgumentException(Errors.format(
                    Errors.Keys.EmptyProperty_1, isEmpty ? SEPARATOR_KEY : HEAD_SEPARATOR_KEY));
        }
        return DefaultNameSpace.forName(name.toFullyQualifiedName(), headSeparator, separator);
    }

    /**
     * Creates a type name from the given character sequence.
     * The default implementation returns a new or an existing {@link DefaultTypeName} instance.
     *
     * @param  scope  the {@linkplain AbstractName#scope() scope} of the type name to be created,
     *                or {@code null} for a global namespace.
     * @param  name   the type name as a string or an international string.
     * @return the type name for the given character sequence.
     *
     * @see #toTypeName(Class)
     * @see Names#createTypeName(CharSequence, String, CharSequence)
     */
    @Override
    public TypeName createTypeName(final NameSpace scope, final CharSequence name) {
        return pool.unique(new DefaultTypeName(scope, name));
    }

    /**
     * Creates a member name from the given character sequence and attribute type.
     * The default implementation returns a new or an existing {@link DefaultMemberName} instance.
     *
     * @param  scope  the {@linkplain AbstractName#scope() scope} of the member name to be created,
     *                or {@code null} for a global namespace.
     * @param  name   the member name as a string or an international string.
     * @param  attributeType  the type of the data associated with the record member.
     * @return the member name for the given character sequence.
     *
     * @see Names#createMemberName(CharSequence, String, CharSequence, Class)
     */
    @Override
    public MemberName createMemberName(final NameSpace scope, final CharSequence name, final TypeName attributeType) {
        return pool.unique(new DefaultMemberName(scope, name, attributeType));
    }

    /**
     * Creates a local name from the given character sequence.
     * The default implementation returns a new or an existing {@link DefaultLocalName} instance.
     *
     * @param  scope  the {@linkplain AbstractName#scope() scope} of the local name to be created,
     *                or {@code null} for a global namespace.
     * @param  name   the local name as a string or an international string.
     * @return the local name for the given character sequence.
     *
     * @see Names#createLocalName(CharSequence, String, CharSequence)
     */
    @Override
    public LocalName createLocalName(final NameSpace scope, final CharSequence name) {
        /*
         * Maintenance note: if the body of this method is modified (except for the use of the cache),
         * consider updating DefaultLocalName.castOrCopy(LocalName) method accordingly.
         */
        if (scope instanceof DefaultNameSpace) {
            // Following may return a cached instance.
            return ((DefaultNameSpace) scope).local(name, null);
        }
        return pool.unique(new DefaultLocalName(scope, name));
    }

    /**
     * Creates a local or scoped name from an array of parsed names. The default implementation
     * returns an instance of {@link DefaultLocalName} if the length of the {@code parsedNames}
     * array is 1, or an instance of {@link DefaultScopedName} if the length of the array is 2
     * or more.
     *
     * @param  scope        the {@linkplain AbstractName#scope() scope} of the generic name to be created,
     *                      or {@code null} for a global namespace.
     * @param  parsedNames  the local names as an array of {@link String} or {@link InternationalString} instances.
     *                      This array shall contain at least one element.
     * @return the generic name for the given parsed names.
     *
     * @see #parseGenericName(NameSpace, CharSequence)
     */
    @Override
    public GenericName createGenericName(final NameSpace scope, final CharSequence... parsedNames) {
        ensureNonNull("parsedNames", parsedNames);
        switch (parsedNames.length) {
            default: return pool.unique(new DefaultScopedName(scope, Arrays.asList(parsedNames)));
            case 1:  return createLocalName(scope, parsedNames[0]); // User may override.
            case 0:  throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, "parsedNames"));
        }
    }

    /**
     * Constructs a generic name from a qualified name.
     * This method splits the given name around a separator inferred from the given scope, or the
     * {@link DefaultNameSpace#DEFAULT_SEPARATOR ':'} separator if the given scope is null.
     *
     * @param  scope  the {@linkplain AbstractName#scope() scope} of the generic name to be created,
     *                or {@code null} for a global namespace.
     * @param  name   the qualified name, as a sequence of names separated by a scope-dependent separator.
     * @return a name parsed from the given string.
     *
     * @see Names#parseGenericName(CharSequence, String, CharSequence)
     */
    @Override
    public GenericName parseGenericName(final NameSpace scope, final CharSequence name) {
        final String separator;
        if (scope instanceof DefaultNameSpace) {
            separator = ((DefaultNameSpace) scope).separator;
        } else {
            separator = DEFAULT_SEPARATOR_STRING;
        }
        final int s = separator.length();
        final List<String> names = new ArrayList<>();
        int lower = 0;
        final String string = name.toString();
        while (true) {
            final int upper = string.indexOf(separator, lower);
            if (upper >= 0) {
                names.add(string.substring(lower, upper));
                lower = upper + s;
            } else {
                names.add(string.substring(lower));
                break;
            }
        }
        if (names.size() == 1) {
            /*
             * Preserves the InternationalString (current implementation of
             * the parsing code above has lost the internationalization).
             */
            return createLocalName(scope, name);
        }
        return createGenericName(scope, names.toArray(new String[names.size()]));
    }

    /**
     * Converts the given value to an array of generic names. If the given value is an instance of
     * {@link GenericName}, {@link String} or any other type enumerated below, then it is converted
     * and returned in an array of length 1. If the given value is an array or a collection, then an
     * array of same length is returned where each element has been converted.
     *
     * <p>Allowed types or element types are:</p>
     * <ul>
     *   <li>{@link GenericName}, to be casted and returned as-is.</li>
     *   <li>{@link CharSequence} (usually a {@link String} or an {@link InternationalString}),
     *       to be parsed as a generic name using the {@link DefaultNameSpace#DEFAULT_SEPARATOR ':'} separator.</li>
     *   <li>{@link Identifier}, its {@linkplain Identifier#getCode() code} to be parsed as a generic name
     *       using the {@link DefaultNameSpace#DEFAULT_SEPARATOR ':'} separator.</li>
     * </ul>
     *
     * If {@code value} is an array or a collection containing {@code null} elements,
     * then the corresponding element in the returned array will also be {@code null}.
     *
     * @param  value  the object to cast into an array of generic names, or {@code null}.
     * @return the generic names, or {@code null} if the given {@code value} was null.
     *         Note that it may be the {@code value} reference itself casted to {@code GenericName[]}.
     * @throws ClassCastException if {@code value} can't be casted.
     *
     * @since 0.5
     */
    public GenericName[] toGenericNames(Object value) throws ClassCastException {
        if (value == null) {
            return null;
        }
        GenericName name = toGenericName(value);
        if (name != null) {
            return new GenericName[] {
                name
            };
        }
        /*
         * Above code checked for a singleton. Now check for a collection or an array.
         */
        final Object[] values;
        if (value instanceof Object[]) {
            values = (Object[]) value;
            if (values instanceof GenericName[]) {
                return (GenericName[]) values;
            }
        } else if (value instanceof Collection<?>) {
            values = ((Collection<?>) value).toArray();
        } else {
            throw new ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_2,
                    "value", value.getClass()));
        }
        final GenericName[] names = new GenericName[values.length];
        for (int i=0; i<values.length; i++) {
            value = values[i];
            if (value != null) {
                name = toGenericName(value);
                if (name == null) {
                    throw new ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_2,
                            Strings.toIndexed("value", i), value.getClass()));
                }
                names[i] = name;
            }
        }
        return names;
    }

    /**
     * Creates a generic name from the given value. The value may be an instance of
     * {@link GenericName}, {@link Identifier}, {@link CharSequence} or {@link Class}.
     * If the given object is not recognized, then this method returns {@code null}.
     *
     * @param  value  the object to convert.
     * @return the converted object, or {@code null} if {@code value} is not convertible.
     */
    private GenericName toGenericName(final Object value) {
        if (value instanceof GenericName) {
            return (GenericName) value;
        }
        if (value instanceof Identifier) {
            return parseGenericName(null, ((Identifier) value).getCode());
        }
        if (value instanceof CharSequence) {
            return parseGenericName(null, (CharSequence) value);
        }
        if (value instanceof Class<?>) {
            return toTypeName((Class<?>) value);
        }
        return null;
    }

    /**
     * Suggests a type name for the given class. Apache SIS provides a mapping between {@code Class}
     * and {@code TypeName} objects as documented in the {@link DefaultTypeName} javadoc.
     *
     * <p>In order to protect against potential changes in the {@code Class} ↔ {@code TypeName} mapping, users are
     * encouraged to retrieve the {@code valueClass} by invoking the {@link Names#toClass(TypeName)} method instead
     * than parsing the name.</p>
     *
     * @param  valueClass  the Java class for which to get a type name, or {@code null}.
     * @return a suggested type name, or {@code null} if the given class was null.
     *
     * @see DefaultTypeName#toClass()
     * @see Names#toClass(TypeName)
     *
     * @since 0.5
     */
    public TypeName toTypeName(final Class<?> valueClass) {
        if (!TypeNames.isValid(valueClass)) {
            return null;
        }
        /*
         * Note: we do not cache the TypeName for the valueClass argument because:
         *
         *  - It is not needed (at least in the default implementation) for getting unique instance.
         *  - It is not the best place for performance improvement, since TypeName are usually only
         *    a step in the creation of bigger object (typically AttributeType). Users are better to
         *    cache the bigger object instead.
         */
        TypeNames t = typeNames;
        if (t == null) {
            /*
             * Create TypeNames outide the synchronized block because the TypeNames constructor will call back
             * methods from this class. Since those methods are overrideable, this could invoke user's code.
             * Note also that methods in this class use the 'pool', which is itself synchronized, so we are
             * better to avoid double synchronization for reducing the risk of dead-lock.
             */
            final TypeNames c = new TypeNames(this);
            synchronized (this) {                       // Double-check strategy is ok if 'typeNames' is volatile.
                t = typeNames;
                if (t == null) {
                    typeNames = t = c;
                }
            }
        }
        return t.toTypeName(this, valueClass);
    }
}
