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

import java.util.Map;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.opengis.util.NameSpace;
import org.opengis.util.LocalName;
import org.opengis.util.ScopedName;
import org.opengis.util.GenericName;
import org.opengis.util.NameFactory;
import org.opengis.util.InternationalString;
import org.apache.sis.util.resources.Errors;
import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.Identifier;
import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.parameter.InvalidParameterValueException;
import org.apache.sis.internal.metadata.NameToIdentifier;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.util.ArgumentChecks;


/**
 * An identification of a CRS object which is both a {@link Identifier} and a {@link GenericName}.
 * This class implements both interfaces in order to allow usage of the same instance either as an object
 * {@linkplain AbstractIdentifiedObject#getName() name} or {@linkplain AbstractIdentifiedObject#getAlias() alias}.
 * This flexibility make easier to uses object's names in two different models:
 *
 * <ul>
 *   <li>In the ISO 19111 model, objects have a single name of type {@code RS_Identifier} and an arbitrary amount
 *       of aliases of type {@code GenericName}.</li>
 *   <li>In the GML model, objects have an arbitrary amount of names of type {@code gml:CodeType},
 *       but do not have any alias.</li>
 * </ul>
 *
 * By using this {@code NamedIdentifier} class, users can declare supplemental object's names as
 * {@linkplain AbstractIdentifiedObject#getAlias() aliases} and have those names used in contexts
 * where {@code Identifier} instances are required, like GML marshalling time.
 *
 * <h2>Name ↔ Identifier mapping</h2>
 * The {@code GenericName} attributes will be inferred from {@code Identifier} attributes as below:
 *
 * <ul>
 *   <li><b>{@linkplain #tip() Tip}:</b> derived from the identifier {@linkplain #getCode() code}.</li>
 *   <li><b>{@linkplain #head() Head}:</b> derived from the identifier {@linkplain #getCodeSpace() code space} if non-null.
 *     If there is no code space, then the scope is derived from the shortest {@linkplain #getAuthority() authority}'s
 *     {@linkplain Citation#getAlternateTitles() alternate titles}, or the {@linkplain Citation#getTitle() main title}
 *     if there is no alternate titles. This policy exploits the ISO 19115 comment saying that citation alternate titles
 *     often contain abbreviation (for example "DCW" as an alternative title for <cite>"Digital Chart of the World"</cite>).</li>
 * </ul>
 *
 * <div class="note"><b>Example:</b>
 * If the identifier attributes are {@code authority} = {@code new DefaultCitation("IOGP")},
 * {@code codeSpace} = {@code "EPSG"} and {@code code} = {@code "4326"}, then the name attributes will be
 * {@code head} = {@code "EPSG"}, {@code tip} = {@code "4326"} and {@link #toString()} = {@code "EPSG:4326"}.
 * Note that the scope does not appear in the string representation of names.</div>
 *
 *
 * <h2>Immutability and thread safety</h2>
 * This class is immutable and thus inherently thread-safe if the {@link Citation} and {@link InternationalString}
 * arguments given to the constructor are also immutable. It is caller's responsibility to ensure that those
 * conditions hold, for example by invoking {@link org.apache.sis.metadata.iso.citation.DefaultCitation#transitionTo
 * DefaultCitation.transitionTo(DefaultCitation.State.FINAL)} before passing the arguments to the constructor.
 * Subclasses shall make sure that any overridden methods remain safe to call from multiple threads and do not change
 * any public {@code NamedIdentifier} state.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 1.0
 *
 * @see org.apache.sis.metadata.iso.DefaultIdentifier
 * @see org.apache.sis.util.iso.AbstractName
 * @see AbstractIdentifiedObject#getName()
 *
 * @since 0.4
 * @module
 */
public class NamedIdentifier extends ImmutableIdentifier implements GenericName, ReferenceIdentifier {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -3982456534858346939L;

    /**
     * The name of this identifier as a generic name.
     * If {@code null}, will be constructed only when first needed.
     */
    private transient GenericName name;

    /**
     * {@code true} if {@link #name} has been given explicitly by the user.
     * Consider this field as final - it is not only for constructors convenience.
     */
    private transient boolean isNameSupplied;

    /**
     * Creates a new identifier from the specified one. This is a copy constructor which get the code,
     * codespace, authority, version and the description (if available) from the given identifier.
     *
     * <p>If the given identifier implements the {@link GenericName} interface, then calls to
     * {@link #tip()}, {@link #head()}, {@link #scope()} and similar methods will delegate
     * to that name.</p>
     *
     * @param  identifier  the identifier to copy.
     *
     * @see #castOrCopy(Identifier)
     */
    public NamedIdentifier(final Identifier identifier) {
        super(identifier);
        if (identifier instanceof GenericName) {
            name = (GenericName) identifier;
            isNameSupplied = true;
        }
    }

    /**
     * Creates a new identifier from the specified name. This constructor infers the identifier attributes
     * (code, codespace and authority) from the given name. Calls to name-related methods like {@link #tip()},
     * {@link #head()} and {@link #scope()} will delegate to the given name.
     *
     * @param  name  the name to wrap.
     *
     * @see #castOrCopy(GenericName)
     */
    public NamedIdentifier(final GenericName name) {
        super(name instanceof Identifier ? (Identifier) name : new NameToIdentifier(name));
        this.name = name;
        isNameSupplied = true;
    }

    /**
     * Constructs an identifier from the given properties. The content of the properties map is used as
     * described in the {@linkplain ImmutableIdentifier#ImmutableIdentifier(Map) super-class constructor},
     * with the addition of an optional {@code "name"} property.
     *
     * <table class="sis">
     *   <caption>Recognized properties</caption>
     *   <tr>
     *     <th>Property name</th>
     *     <th>Value type</th>
     *     <th>Returned by</th>
     *   </tr>
     *   <tr>
     *     <td>{@code "name"}</td>
     *     <td>{@link GenericName}</td>
     *     <td>(none)</td>
     *   </tr>
     *   <tr>
     *     <th colspan="3" class="hsep">Defined in parent class (reminder)</th>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.metadata.Identifier#CODE_KEY}</td>
     *     <td>{@link String}</td>
     *     <td>{@link #getCode()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.metadata.Identifier#CODESPACE_KEY}</td>
     *     <td>{@link String}</td>
     *     <td>{@link #getCodeSpace()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.metadata.Identifier#AUTHORITY_KEY}</td>
     *     <td>{@link String} or {@link Citation}</td>
     *     <td>{@link #getAuthority()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.metadata.Identifier#VERSION_KEY}</td>
     *     <td>{@link String}</td>
     *     <td>{@link #getVersion()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.metadata.Identifier#DESCRIPTION_KEY}</td>
     *     <td>{@link String} or {@link InternationalString}</td>
     *     <td>{@link #getDescription()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.apache.sis.referencing.AbstractIdentifiedObject#LOCALE_KEY}</td>
     *     <td>{@link Locale}</td>
     *     <td>(none)</td>
     *   </tr>
     * </table>
     *
     * The {@value org.opengis.metadata.Identifier#CODE_KEY} property is mandatory and all other properties
     * are optional. If a {@code "name"} property is provided, then calls to name-related methods like
     * {@link #tip()}, {@link #head()} and {@link #scope()} will delegate to the given name.
     *
     * @param  properties  the properties to be given to this identifier.
     * @throws InvalidParameterValueException if a property has an invalid value.
     * @throws IllegalArgumentException if a property is invalid for some other reason.
     */
    public NamedIdentifier(final Map<String,?> properties) throws IllegalArgumentException {
        super(properties);
        name = (GenericName) properties.get("name");
        isNameSupplied = (name != null);
    }

    /**
     * Constructs an identifier from an authority and code.
     * This is a convenience constructor for commonly-used parameters.
     *
     * <p>If the given code is an {@link InternationalString}, then the {@code code.toString(Locale.ROOT)}
     * return value will be used for the {@link #getCode() code} property, and the complete international
     * string will be used for the {@link #getName() name} property.</p>
     *
     * @param authority
     *          organization or party responsible for definition and maintenance of the code space or code,
     *          or {@code null} if not available.
     * @param code
     *          identifier code or name, optionally from a controlled list or pattern defined by the authority.
     *          The code can not be null.
     */
    public NamedIdentifier(final Citation authority, final CharSequence code) {
        super(authority, Citations.toCodeSpace(authority), toString(code));
        if (code instanceof InternationalString) {
            name = createName(authority, super.getCodeSpace(), code);
            isNameSupplied = true;                              // Because 'code' is an international string.
        }
    }

    /**
     * Constructs an identifier from an authority and localizable code,
     * with an optional version number and description.
     *
     * <p>If the given code is an {@link InternationalString}, then the {@code code.toString(Locale.ROOT)}
     * return value will be used for the {@link #getCode() code} property, and the complete international
     * string will be used for the {@link #getName() name} property.</p>
     *
     * @param authority
     *          organization or party responsible for definition and maintenance of the code space or code,
     *          or {@code null} if not available.
     * @param codeSpace
     *          name or identifier of the person or organization responsible for namespace, or {@code null}
     *          if not available. This is often an abbreviation of the authority name.
     * @param code
     *          identifier code or name, optionally from a controlled list or pattern defined by a code space.
     *          The code can not be null.
     * @param version
     *          the version of the associated code space or code as specified by the code authority,
     *          or {@code null} if none.
     * @param description
     *          natural language description of the meaning of the code value, or {@code null} if none.
     */
    public NamedIdentifier(final Citation authority, final String codeSpace, final CharSequence code,
            final String version, final InternationalString description)
    {
        super(authority, codeSpace, toString(code), version, description);
        if (code instanceof InternationalString) {
            name = createName(authority, codeSpace, code);
            isNameSupplied = true;                              // Because 'code' is an international string.
        }
    }

    /**
     * Returns the unlocalized string representation of the given code.
     */
    private static String toString(final CharSequence code) {
        ArgumentChecks.ensureNonNull("code", code);
        final String c;
        if (code instanceof InternationalString) {
            c = ((InternationalString) code).toString(Locale.ROOT);
        } else {
            c = code.toString();
        }
        if (c != null) {
            return c;
        }
        /*
         * May happen if the user gave us an instance of 'org.apache.sis.internal.jaxb.gcx.Anchor' class
         * (maybe he got the instance indirectly) and the construction of that instance is not completed.
         */
        throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentClass_2, "code", code.getClass()));
    }

    /**
     * Returns the generic name of this identifier.
     * The name will be constructed automatically the first time it will be needed.
     * The name's head is inferred from the shortest alternative title (if any).
     * This heuristic rule is compatible to the ISO 19115 remark saying that the
     * {@linkplain Citation#getAlternateTitles() alternate titles} often contains abbreviation
     * (for example "DCW" as an alternative title for "Digital Chart of the World").
     * If no alternative title is found or if the main title is yet shorter, then it is used.
     *
     * @category Generic name
     */
    private synchronized GenericName getName() {
        if (name == null) {
            name = createName(super.getAuthority(), super.getCodeSpace(), super.getCode());
        }
        return name;
    }

    /**
     * Constructs a generic name from the specified authority and code.
     *
     * @param  authority  the authority, or {@code null} if none.
     * @param  codeSpace  the code space, or {@code null} if none.
     * @param  code       the code.
     * @return a new generic name for the given authority and code.
     * @category Generic name
     *
     * @see <a href="https://issues.apache.org/jira/browse/SIS-197">SIS-197</a>
     */
    private static GenericName createName(final Citation authority, String codeSpace, final CharSequence code) {
        if (codeSpace == null) {
            codeSpace = Citations.toCodeSpace(authority);           // Whitespaces trimed by Citations.
        }
        final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
        if (codeSpace != null) {
            return factory.createGenericName(null, codeSpace, code);
        } else {
            return factory.createLocalName(null, code);
        }
    }

    /**
     * Returns a SIS identifier implementation with the values of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code NamedIdentifier}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code NamedIdentifier} instance is created using the
     *       {@linkplain #NamedIdentifier(Identifier) copy constructor} and returned.
     *       Note that this is a <cite>shallow</cite> copy operation, since the other
     *       metadata contained in the given object are not recursively copied.</li>
     * </ul>
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     *
     * @since 1.0
     */
    public static NamedIdentifier castOrCopy(final Identifier object) {
        if (object == null || object instanceof NamedIdentifier) {
            return (NamedIdentifier) object;
        }
        return new NamedIdentifier(object);
    }

    /**
     * Returns a SIS name implementation with the values of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code NamedIdentifier}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code NamedIdentifier} instance is created using the
     *       {@linkplain #NamedIdentifier(GenericName) copy constructor} and returned.
     *       Note that this is a <cite>shallow</cite> copy operation, since the other
     *       metadata contained in the given object are not recursively copied.</li>
     * </ul>
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     *
     * @since 1.0
     */
    public static NamedIdentifier castOrCopy(final GenericName object) {
        if (object == null || object instanceof NamedIdentifier) {
            return (NamedIdentifier) object;
        }
        return new NamedIdentifier(object);
    }

    /**
     * The last element in the sequence of {@linkplain #getParsedNames() parsed names}.
     * By default, this is the same value than the {@linkplain #getCode() code} provided as a local name.
     *
     * @return the last element in the list of {@linkplain #getParsedNames() parsed names}.
     *
     * @see #getCode()
     */
    @Override
    public LocalName tip() {
        return getName().tip();
    }

    /**
     * Returns the first element in the sequence of {@linkplain #getParsedNames() parsed names}.
     * By default, this is the same value than the {@linkplain #getCodeSpace() code space} provided as a local name.
     *
     * @return the first element in the list of {@linkplain #getParsedNames() parsed names}.
     *
     * @see #scope()
     * @see #getCodeSpace()
     */
    @Override
    public LocalName head() {
        return getName().head();
    }

    /**
     * Returns the scope (name space) in which this name is local.
     * By default, this is the same value than the {@link #getAuthority() authority} provided as a name space.
     *
     * @see #head()
     * @see #getAuthority()
     *
     * @return the scope of this name.
     */
    @Override
    public NameSpace scope() {
        return getName().scope();
    }

    /**
     * Returns the depth of this name within the namespace hierarchy.
     *
     * @return the depth of this name.
     */
    @Override
    public int depth() {
        return getName().depth();
    }

    /**
     * Returns the sequence of {@linkplain LocalName local names} making this generic name.
     * The length of this sequence is the {@linkplain #depth() depth}.
     * It does not include the {@linkplain #scope() scope}.
     *
     * @return the local names making this generic name, without the {@linkplain #scope() scope}.
     *         Shall never be {@code null} neither empty.
     */
    @Override
    public List<? extends LocalName> getParsedNames() {
        return getName().getParsedNames();
    }

    /**
     * Returns this name expanded with the specified scope. One may represent this operation
     * as a concatenation of the specified {@code name} with {@code this}.
     *
     * @param scope The name to use as prefix.
     * @return a concatenation of the given scope with this name.
     */
    @Override
    public ScopedName push(final GenericName scope) {
        return getName().push(scope);
    }

    /**
     * Returns a view of this name as a fully-qualified name.
     *
     * @return the fully-qualified name (never {@code null}).
     */
    @Override
    public GenericName toFullyQualifiedName() {
        return getName().toFullyQualifiedName();
    }

    /**
     * Returns a local-dependent string representation of this generic name.
     * This string is similar to the one returned by {@link #toString()} except that each element has
     * been localized in the {@linkplain InternationalString#toString(Locale) specified locale}.
     * If no international string is available, then this method returns an implementation mapping
     * to {@code toString()} for all locales.
     *
     * @return a localizable string representation of this name.
     */
    @Override
    public InternationalString toInternationalString() {
        return getName().toInternationalString();
    }

    /**
     * Returns a string representation of this generic name. This string representation
     * is local-independent. It contains all elements listed by {@link #getParsedNames()}
     * separated by a namespace-dependent character (usually {@code :} or {@code /}).
     *
     * @return a local-independent string representation of this generic name.
     *
     * @see IdentifiedObjects#toString(Identifier)
     */
    @Override
    public String toString() {
        return getName().toString();
    }

    /**
     * Compares this name with the specified object for order. Returns a negative integer,
     * zero, or a positive integer as this name lexicographically precedes, is equal to,
     * or follows the specified object.
     *
     * @param  object  the object to compare with.
     * @return -1 if this identifier precedes the given object, +1 if it follows it.
     */
    @Override
    public int compareTo(final GenericName object) {
        return getName().compareTo(object);
    }

    /**
     * Compares this identifier with the specified object for equality.
     *
     * @param  object  the object to compare with this name.
     * @return {@code true} if the given object is equal to this name.
     */
    @Override
    public boolean equals(final Object object) {
        if (object == this) {
            return true;
        }
        if (super.equals(object)) {
            if (!isNameSupplied) {
                return true;            // No need to compare names if they are computed from the same values.
            }
            final NamedIdentifier that = (NamedIdentifier) object;
            return Objects.equals(this.getName(), that.getName());
        }
        return false;
    }

    /**
     * Returns a hash code value for this object.
     */
    @Override
    public int hashCode() {
        /*
         * We do not use the name because it is usually inferred from existing properties.
         * We only revert the bits for differentiating this NamedIdentifier class from its parent class.
         */
        return ~super.hashCode();
    }

    /**
     * Invoked on serialization for writing the {@linkplain #name} if it was supplied by the user.
     * Otherwise, we will let {@link #getName()} recompute the name only when needed.
     *
     * @param  out  the output stream where to serialize this named identifier.
     * @throws IOException if an I/O error occurred while writing.
     */
    private void writeObject(final ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeObject(isNameSupplied ? name : null);
    }

    /**
     * Invoked on deserialization for reading the name written by {@link #writeObject(ObjectOutputStream)},
     * if any.
     *
     * @param  in  the input stream from which to deserialize a named identifier.
     * @throws IOException if an I/O error occurred while reading or if the stream contains invalid data.
     * @throws ClassNotFoundException if the class serialized on the stream is not on the classpath.
     */
    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        name = (GenericName) in.readObject();
        isNameSupplied = (name != null);
    }
}
