/*
 * 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.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
import org.opengis.parameter.InvalidParameterValueException;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.metadata.privy.NameToIdentifier;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.util.iso.DefaultNameFactory;


/**
 * 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 number 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 are 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 <q>Digital Chart of the World</q>).</li>
 * </ul>
 *
 * <h3>Example</h3>
 * 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.
 *
 *
 * <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.4
 *
 * @see org.apache.sis.metadata.iso.DefaultIdentifier
 * @see org.apache.sis.util.iso.AbstractName
 * @see AbstractIdentifiedObject#getName()
 *
 * @since 0.4
 */
public class NamedIdentifier extends ImmutableIdentifier implements GenericName {
    /**
     * 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 cannot 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 cannot 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) {
        // Implicit null check below.
        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.xml.bind.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 = DefaultNameFactory.provider();
        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 <em>shallow</em> copy operation, because 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 <em>shallow</em> copy operation, because 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 as 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 as 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 as 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 module path.
     */
    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        name = (GenericName) in.readObject();
        isNameSupplied = (name != null);
    }
}
