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

import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import org.opengis.util.ScopedName;
import org.opengis.util.GenericName;
import org.opengis.util.InternationalString;
import org.apache.sis.internal.feature.Resources;
import org.apache.sis.feature.AbstractIdentifiedType;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.NullArgumentException;
import org.apache.sis.util.Deprecable;
import org.apache.sis.util.Localized;
import org.apache.sis.util.Classes;


/**
 * Information common to all kind of types (feature, association, characteristics).
 * Those information are:
 *
 * <ul>
 *   <li>the name        — a unique name which can be defined within a scope (or namespace).</li>
 *   <li>the definition  — a concise definition of the element.</li>
 *   <li>the designation — a natural language designator for the element for user interfaces.</li>
 *   <li>the description — information beyond that required for concise definition of the element.</li>
 * </ul>
 *
 * The name is mandatory and can be specified as either {@link org.opengis.util.LocalName},
 * {@link org.opengis.util.ScopedName}, {@link String} or {@link InternationalString} instance.
 * All other properties are optional.
 *
 * <div class="section">Default namespace</div>
 * In many cases, the names of all {@code AttributeType}s and {@code AssociationRole}s to create
 * within a {@code FeatureType} share the same namespace.
 * For making name creations more convenient, the namespace can be
 * {@linkplain FeatureTypeBuilder#setNameSpace specified once} and applied automatically
 * to all names created by the {@link #setName(CharSequence)} method.
 * Note that namespaces will not be visible in the name {@linkplain org.apache.sis.util.iso.DefaultLocalName#toString()
 * string representation} unless the {@linkplain org.apache.sis.util.iso.DefaultLocalName#toFullyQualifiedName() fully
 * qualified name} is requested.
 * Example:
 *
 * {@preformat java
 *     FeatureTypeBuilder builder = new FeatureTypeBuilder().setNameSpace("MyNameSpace").setName("City");
 *     FeatureType city = builder.build();
 *
 *     System.out.println(city.getName());                              // Prints "City"
 *     System.out.println(city.getName().toFullyQualifiedName());       // Prints "MyNameSpace:City"
 * }
 *
 * @author  Johann Sorel (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 * @since   0.8
 * @module
 */
public abstract class TypeBuilder implements Localized {
    /**
     * The feature name, definition, designation and description.
     * The name is mandatory; all other information are optional.
     */
    private final Map<String,Object> identification;

    /**
     * Creates a new builder initialized to the values of the given builder.
     * This constructor is for {@link AttributeTypeBuilder#setValueClass(Class)}
     * and {@link CharacteristicTypeBuilder#setValueClass(Class)} implementations.
     *
     * @param builder  the builder from which to copy information.
     */
    TypeBuilder(final TypeBuilder builder) {
        identification = new HashMap<>(builder.identification);
    }

    /**
     * Creates a new builder initialized to the given configuration.
     */
    TypeBuilder(final Locale locale) {
        identification = new HashMap<>(4);
        putIfNonNull(Errors.LOCALE_KEY, locale);
    }

    /**
     * Resets the identification map. After invoking this method, this {@code TypeBuilder}
     * is in same state that after it has been {@linkplain #TypeBuilder(Locale) constructed}.
     *
     * @see #clearCache()
     */
    final void reset() {
        final Object locale = identification.get(Errors.LOCALE_KEY);
        identification.clear();
        putIfNonNull(Errors.LOCALE_KEY, locale);
    }

    /**
     * Initializes this builder to the value of the given type.
     * The caller is responsible to invoke {@link #reset()} (if needed) before this method.
     */
    final void initialize(final AbstractIdentifiedType template) {
        putIfNonNull(AbstractIdentifiedType.NAME_KEY,        template.getName());
        putIfNonNull(AbstractIdentifiedType.DEFINITION_KEY,  template.getDefinition());
        putIfNonNull(AbstractIdentifiedType.DESIGNATION_KEY, template.getDesignation());
        putIfNonNull(AbstractIdentifiedType.DESCRIPTION_KEY, template.getDescription());
        if (template instanceof Deprecable && ((Deprecable) template).isDeprecated()) {
            identification.put(AbstractIdentifiedType.DEPRECATED_KEY, Boolean.TRUE);
        }
    }

    /**
     * Puts the given value in the {@link #identification} map if the value is non-null.
     * This method should be invoked only when the {@link #identification} map is known
     * to not contain any value for the given key.
     */
    private void putIfNonNull(final String key, final Object value) {
        if (value != null) {
            identification.put(key, value);
        }
    }

    /**
     * Returns the map of properties to give to the {@code FeatureType} or {@code PropertyType} constructor.
     * If the map does not contains a name, a default name may be generated.
     */
    @SuppressWarnings("ReturnOfCollectionOrArrayField")
    final Map<String,Object> identification() {
        if (identification.get(AbstractIdentifiedType.NAME_KEY) == null) {
            String name = getDefaultName();
            if (name != null) {
                final int length = name.length();
                if (length != 0) {
                    final int c  = name.codePointAt(0);
                    final int lc = Character.toLowerCase(c);
                    if (c != lc) {
                        final int n = Character.charCount(c);
                        if (n >= length || Character.isLowerCase(name.codePointAt(n))) {
                            final StringBuilder buffer = new StringBuilder(length);
                            name = buffer.appendCodePoint(lc).append(name, n, length).toString();
                        }
                    }
                    identification.put(AbstractIdentifiedType.NAME_KEY, createLocalName(name));
                }
            }
        }
        return identification;
    }

    /**
     * If the object created by the last call to {@code build()} has been cached, clears that cache.
     *
     * @see #reset()
     */
    abstract void clearCache();

    /**
     * Creates a local name in the {@linkplain FeatureTypeBuilder#setNameSpace feature namespace}.
     */
    abstract GenericName createLocalName(final CharSequence name);

    /**
     * Creates a generic name in the {@linkplain FeatureTypeBuilder#setNameSpace feature namespace}.
     */
    abstract GenericName createGenericName(final CharSequence... names);

    /**
     * Returns the name of the {@code IdentifiedType} to create, or {@code null} if undefined.
     * This method returns the value built from the last call to a {@code setName(…)} method,
     * or a default name or {@code null} if no name has been explicitly specified.
     *
     * @return the name of the {@code IdentifiedType} to create (may be a default name or {@code null}).
     *
     * @see #setName(GenericName)
     * @see AbstractIdentifiedType#getName()
     * @see FeatureTypeBuilder#getNameSpace()
     */
    public GenericName getName() {
        return (GenericName) identification().get(AbstractIdentifiedType.NAME_KEY);
    }

    /**
     * Returns a default name to use if the user did not specified a name. The first letter will be changed to
     * lower case (unless the name looks like an acronym) for compliance with Java convention on property names.
     */
    String getDefaultName() {
        return null;
    }

    /**
     * Returns the name to use for displaying error messages.
     */
    final String getDisplayName() {
        final GenericName name = getName();
        return (name != null) ? name.toString() : Vocabulary.getResources(identification).getString(Vocabulary.Keys.Unnamed);
    }

    /**
     * Sets the {@code IdentifiedType} name as a generic name.
     * If another name was defined before this method call, that previous value will be discarded.
     *
     * <div class="note"><b>Note for subclasses:</b>
     * all {@code setName(…)} convenience methods in this builder delegate to this method.
     * Consequently this method can be used as a central place where to control the creation of all names.</div>
     *
     * @param  name  the generic name (can not be {@code null}).
     * @return {@code this} for allowing method calls chaining.
     *
     * @see #getName()
     * @see #setName(CharSequence)
     * @see AbstractIdentifiedType#NAME_KEY
     */
    public TypeBuilder setName(final GenericName name) {
        ensureNonNull("name", name);
        if (!name.equals(identification.put(AbstractIdentifiedType.NAME_KEY, name))) {
            clearCache();
        }
        return this;
    }

    /**
     * Sets the {@code IdentifiedType} name as a simple string (local name).
     * The namespace will be the value specified by the last call to {@link FeatureTypeBuilder#setNameSpace(CharSequence)},
     * but that namespace will not be visible in the {@linkplain org.apache.sis.util.iso.DefaultLocalName#toString()
     * string representation} unless the {@linkplain org.apache.sis.util.iso.DefaultLocalName#toFullyQualifiedName()
     * fully qualified name} is requested.
     *
     * <p>This convenience method creates a {@link org.opengis.util.LocalName} instance from
     * the given {@code CharSequence}, then delegates to {@link #setName(GenericName)}.</p>
     *
     * @param  localPart  the local part of the generic name as a {@link String} or {@link InternationalString}.
     * @return {@code this} for allowing method calls chaining.
     *
     * @see #getName()
     * @see #setName(CharSequence...)
     * @see FeatureTypeBuilder#getNameSpace()
     */
    public TypeBuilder setName(final CharSequence localPart) {
        ensureNonEmpty("localPart", localPart);
        return setName(createLocalName(localPart));
    }

    /**
     * Sets the {@code IdentifiedType} name as a string in the given scope.
     * The {@code components} array must contain at least one element.
     * The last component (the {@linkplain org.apache.sis.util.iso.DefaultScopedName#tip() tip}) will be sufficient
     * in many cases for calls to the {@link org.apache.sis.feature.AbstractFeature#getProperty(String)} method.
     * The other elements before the last one are optional and can be used for resolving ambiguity.
     * They will be visible as the name {@linkplain org.apache.sis.util.iso.DefaultScopedName#path() path}.
     *
     * <div class="note"><b>Example:</b>
     * a call to {@code setName("A", "B", "C")} will create a "A:B:C" name.
     * A property built with this name can be obtained from a feature by a call to {@code feature.getProperty("C")}
     * if there is no ambiguity, or otherwise by a call to {@code feature.getProperty("B:C")} (if non-ambiguous) or
     * {@code feature.getProperty("A:B:C")}.</div>
     *
     * In addition to the path specified by the {@code components} array, the name may also contain
     * a namespace specified by the last call to {@link FeatureTypeBuilder#setNameSpace(CharSequence)}.
     * But contrarily to the specified components, the namespace will not be visible in the name
     * {@linkplain org.apache.sis.util.iso.DefaultScopedName#toString() string representation} unless the
     * {@linkplain org.apache.sis.util.iso.DefaultScopedName#toFullyQualifiedName() fully qualified name} is requested.
     *
     * <p>This convenience method creates a {@link org.opengis.util.LocalName} or {@link org.opengis.util.ScopedName}
     * instance depending on whether the {@code names} array contains exactly 1 element or more than 1 element, then
     * delegates to {@link #setName(GenericName)}.</p>
     *
     * @param  components  the name components as an array of {@link String} or {@link InternationalString} instances.
     * @return {@code this} for allowing method calls chaining.
     *
     * @see #getName()
     * @see #setName(CharSequence)
     * @see FeatureTypeBuilder#getNameSpace()
     */
    public TypeBuilder setName(final CharSequence... components) {
        ensureNonNull("components", components);
        if (components.length == 0) {
            throw new IllegalArgumentException(errors().getString(Errors.Keys.EmptyArgument_1, "components"));
        }
        return setName(createGenericName(components));
    }

    /**
     * Returns a concise definition of the element.
     *
     * @return concise definition of the element, or {@code null} if none.
     *
     * @see AbstractIdentifiedType#getDefinition()
     */
    public CharSequence getDefinition() {
        return (CharSequence) identification.get(AbstractIdentifiedType.DEFINITION_KEY);
    }

    /**
     * Sets a concise definition of the element.
     *
     * @param  definition  a concise definition of the element, or {@code null} if none.
     * @return {@code this} for allowing method calls chaining.
     *
     * @see #getDefinition()
     * @see AbstractIdentifiedType#DEFINITION_KEY
     */
    public TypeBuilder setDefinition(final CharSequence definition) {
        if (!Objects.equals(definition, identification.put(AbstractIdentifiedType.DEFINITION_KEY, definition))) {
            clearCache();
        }
        return this;
    }

    /**
     * Returns a natural language designator for the element.
     * This can be used as an alternative to the {@linkplain #getName() name} in user interfaces.
     *
     * @return natural language designator for the element, or {@code null} if none.
     *
     * @see AbstractIdentifiedType#getDesignation()
     */
    public CharSequence getDesignation() {
        return (CharSequence) identification.get(AbstractIdentifiedType.DESIGNATION_KEY);
    }

    /**
     * Sets a natural language designator for the element.
     * This can be used as an alternative to the {@linkplain #getName() name} in user interfaces.
     *
     * @param  designation  a natural language designator for the element, or {@code null} if none.
     * @return {@code this} for allowing method calls chaining.
     *
     * @see #getDesignation()
     * @see AbstractIdentifiedType#DESIGNATION_KEY
     */
    public TypeBuilder setDesignation(final CharSequence designation) {
        if (!Objects.equals(designation, identification.put(AbstractIdentifiedType.DESIGNATION_KEY, designation))) {
            clearCache();
        }
        return this;
    }

    /**
     * Returns optional information beyond that required for concise definition of the element.
     * The description may assist in understanding the element scope and application.
     *
     * @return information beyond that required for concise definition of the element, or {@code null} if none.
     *
     * @see AbstractIdentifiedType#getDescription()
     */
    public CharSequence getDescription() {
        return (CharSequence) identification.get(AbstractIdentifiedType.DESCRIPTION_KEY);
    }

    /**
     * Sets optional information beyond that required for concise definition of the element.
     * The description may assist in understanding the feature scope and application.
     * If the type {@linkplain #isDeprecated() is deprecated}, then the description should
     * give indication about the replacement (e.g. <cite>"superceded by …"</cite>).
     *
     * @param  description  information beyond that required for concise definition of the element, or {@code null} if none.
     * @return {@code this} for allowing method calls chaining.
     *
     * @see #getDescription()
     * @see AbstractIdentifiedType#DESCRIPTION_KEY
     */
    public TypeBuilder setDescription(final CharSequence description) {
        if (!Objects.equals(description, identification.put(AbstractIdentifiedType.DESCRIPTION_KEY, description))) {
            clearCache();
        }
        return this;
    }

    /**
     * Returns {@code true} if the type is deprecated.
     * If this method returns {@code true}, then the {@linkplain #getDescription() description} should give
     * indication about the replacement (e.g. <cite>"superceded by …"</cite>).
     *
     * @return whether this type is deprecated.
     *
     * @see AbstractIdentifiedType#isDeprecated()
     */
    public boolean isDeprecated() {
        return Boolean.TRUE.equals(identification.get(AbstractIdentifiedType.DEPRECATED_KEY));
    }

    /**
     * Sets whether the type is deprecated.
     * If the type is deprecated, then the {@linkplain #setDescription(CharSequence) description}
     * should be set to an indication about the replacement (e.g. <cite>"superceded by …"</cite>).
     *
     * @param  deprecated  whether this type is deprecated.
     * @return {@code this} for allowing method calls chaining.
     *
     * @see #isDeprecated()
     * @see AbstractIdentifiedType#DEPRECATED_KEY
     */
    public TypeBuilder setDeprecated(final boolean deprecated) {
        final Boolean wrapper = deprecated;
        Object previous = identification.put(AbstractIdentifiedType.DEPRECATED_KEY, wrapper);
        if (previous == null) {
            previous = Boolean.FALSE;
        }
        if (!Objects.equals(wrapper, previous)) {
            clearCache();
        }
        return this;
    }

    /**
     * Returns the element of the given name in the given list. The given name does not need to contains
     * all elements of a {@link ScopedName}; it can be only the tip (for example {@code "myName"} instead
     * of {@code "myScope:myName"}) provided that ignoring the name head does not create ambiguity.
     *
     * @param  types         the collection where to search for an element of the given name.
     * @param  name          name of the element to search.
     * @param  nonAmbiguous  whether to throw an exception if the given name is ambiguous.
     * @return element of the given name, or {@code null} if none were found.
     * @throws IllegalArgumentException if the given name is ambiguous.
     */
    @SuppressWarnings("null")
    final <E extends TypeBuilder> E forName(final List<E> types, final String name, final boolean nonAmbiguous) {
        E best      = null;                     // Best type found so far.
        E ambiguity = null;                     // If two types are found at the same depth, the other type.
        int depth   = Integer.MAX_VALUE;        // Number of path elements that we had to ignore in the GenericName.
        for (final E type : types) {
            GenericName candidate = type.getName();
            for (int d=0; candidate != null; d++) {
                if (name.equals(candidate.toString())) {
                    if (d < depth) {
                        best      = type;
                        ambiguity = null;
                        depth     = d;
                        break;
                    }
                    if (d == depth) {
                        ambiguity = type;
                        break;
                    }
                }
                if (!(candidate instanceof ScopedName)) break;
                candidate = ((ScopedName) candidate).tail();
            }
        }
        if (ambiguity != null && nonAmbiguous) {
            throw new IllegalArgumentException(errors().getString(
                    Errors.Keys.AmbiguousName_3, best.getName(), ambiguity.getName(), name));
        }
        return best;
    }

    /**
     * Returns the locale used for formatting error messages, or {@code null} if unspecified.
     * If unspecified, the system default locale will be used.
     *
     * @return the locale used for formatting error messages, or {@code null} if unspecified.
     */
    @Override
    public Locale getLocale() {
        return (Locale) identification.get(Errors.LOCALE_KEY);
    }

    /**
     * Returns the resources for error messages.
     */
    final Errors errors() {
        return Errors.getResources(identification);
    }

    /**
     * Returns the {@code sis-feature} specific resources for error messages.
     */
    final Resources resources() {
        return Resources.forProperties(identification);
    }

    /**
     * Same as {@link org.apache.sis.util.ArgumentChecks#ensureNonNull(String, Object)},
     * but uses the current locale in case of error.
     *
     * @param  name   the name of the argument to be checked. Used only if an exception is thrown.
     * @param  value  the user argument to check against null value.
     * @throws NullArgumentException if {@code object} is null.
     */
    final void ensureNonNull(final String name, final Object value) {
        if (value == null) {
            throw new NullArgumentException(errors().getString(Errors.Keys.NullArgument_1, name));
        }
    }

    /**
     * Ensures that this instance is still alive.
     *
     * @param owner  the owner of this instance. A value of null means that this instance should not be used any more.
     */
    final void ensureAlive(final TypeBuilder owner) {
        if (owner == null) {
            throw new IllegalStateException(errors().getString(Errors.Keys.DisposedInstanceOf_1, getClass()));
        }
    }

    /**
     * Same as {@link org.apache.sis.util.ArgumentChecks#ensureNonEmpty(String, CharSequence)},
     * but uses the current locale in case of error.
     *
     * @param  name  the name of the argument to be checked. Used only if an exception is thrown.
     * @param  text  the user argument to check against null value and empty sequences.
     * @throws NullArgumentException if {@code text} is null.
     * @throws IllegalArgumentException if {@code text} is empty.
     */
    final void ensureNonEmpty(final String name, final CharSequence text) {
        if (text == null) {
            throw new NullArgumentException(errors().getString(Errors.Keys.NullArgument_1, name));
        }
        if (text.length() == 0) {
            throw new IllegalArgumentException(errors().getString(Errors.Keys.EmptyArgument_1, name));
        }
    }

    /**
     * Returns a string representation of this object.
     * The returned string is for debugging purpose only and may change in any future SIS version.
     *
     * @return a string representation of this object for debugging purpose.
     */
    @Override
    public String toString() {
        return appendStringTo(new StringBuilder(Classes.getShortClassName(this))).toString();
    }

    /**
     * Partial implementation of {@link #toString()}. This method assumes that the class name
     * has already be written in the buffer.
     */
    final StringBuilder appendStringTo(final StringBuilder buffer) {
        toStringInternal(buffer.append("[“").append(getDisplayName()).append('”'));
        return buffer.append(']');
    }

    /**
     * Appends a text inside the value returned by {@link #toString()}, before the closing bracket.
     */
    void toStringInternal(StringBuilder buffer) {
    }

    /**
     * Invoked when a type builder has been removed from its parent.
     * Subclasses should override this method in a way that flag the builder as not usable anymore.
     */
    void remove() {
    }

    /**
     * Builds the feature or property type from the information specified to this builder.
     * If a type has already been built and this builder state has not changed since the type creation,
     * then the previously created {@code IdentifiedType} instance is returned.
     *
     * <div class="warning"><b>Warning:</b> In a future SIS version, the return type may be changed to the
     * {@code org.opengis.feature.IdentifiedType} interface. This change is pending GeoAPI revision.</div>
     *
     * @return the feature or property type.
     * @throws IllegalStateException if the builder contains inconsistent information.
     */
    public abstract AbstractIdentifiedType build() throws IllegalStateException;
}
