/*
 * 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.ListIterator;
import java.util.Locale;
import java.util.Objects;
import java.io.Serializable;
import java.io.ObjectStreamException;
import org.apache.sis.internal.util.Constants;
import org.opengis.util.NameSpace;
import org.opengis.util.LocalName;
import org.opengis.util.ScopedName;
import org.opengis.util.GenericName;
import org.opengis.util.InternationalString;
import org.apache.sis.util.collection.WeakValueHashMap;
import org.apache.sis.internal.util.UnmodifiableArrayList;

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


/**
 * A domain in which {@linkplain AbstractName names} given by character strings are defined.
 * This implementation does not support localization in order to avoid ambiguity when testing
 * two namespaces for {@linkplain #equals(Object) equality}.
 *
 * <p>{@code DefaultNameSpace} can be instantiated by any of the following methods:</p>
 * <ul>
 *   <li>{@link DefaultNameFactory#createNameSpace(GenericName, Map)}</li>
 * </ul>
 *
 * <div class="section">Immutability and thread safety</div>
 * This class is immutable and thus inherently thread-safe if the {@link NameSpace} and {@link CharSequence}
 * arguments given to the constructor are also immutable. Subclasses shall make sure that any overridden methods
 * remain safe to call from multiple threads and do not change any public {@code NameSpace} state.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 0.8
 *
 * @see DefaultScopedName
 * @see DefaultLocalName
 * @see DefaultTypeName
 * @see DefaultMemberName
 * @see DefaultNameFactory
 *
 * @since 0.3
 * @module
 */
public class DefaultNameSpace implements NameSpace, Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = 8272640747799127007L;

    /**
     * The default separator, which is {@code ':'}. The separator is inserted between
     * the namespace and any {@linkplain GenericName generic name} in that namespace.
     */
    public static final char DEFAULT_SEPARATOR = Constants.DEFAULT_SEPARATOR;

    /**
     * {@link #DEFAULT_SEPARATOR} as a {@link String}.
     */
    static final String DEFAULT_SEPARATOR_STRING = ":";

    /**
     * The parent namespace, or {@code null} if the parent is the unique {@code GLOBAL} instance.
     * We don't use direct reference to {@code GLOBAL} because {@code null} is used as a sentinel
     * value for stopping iterative searches (using GLOBAL would have higher risk of never-ending
     * loops in case of bug), and in order to reduce the stream size during serialization.
     *
     * @see #parent()
     */
    private final DefaultNameSpace parent;

    /**
     * The name of this namespace, usually as a {@link String} or an {@link InternationalString}.
     */
    private final CharSequence name;

    /**
     * The separator to insert between the namespace and the {@linkplain AbstractName#head() head}
     * of any name in that namespace.
     */
    final String headSeparator;

    /**
     * The separator to insert between the {@linkplain AbstractName#getParsedNames() parsed names}
     * of any name in that namespace.
     */
    final String separator;

    /**
     * The fully qualified name for this namespace.
     * Will be created when first needed.
     */
    private transient AbstractName path;

    /**
     * The children created in this namespace. The values are restricted to the following types:
     *
     * <ul>
     *   <li>{@link DefaultNameSpace}</li>
     *   <li>{@link DefaultLocalName}</li>
     * </ul>
     *
     * No other type should be allowed. The main purpose of this map is to hold child namespaces.
     * However we can (in an opportunist way) handles local names as well. In case of conflict,
     * the namespace will have precedence.
     *
     * <p>This field is initialized by {@link #init()} soon after {@code DefaultNameSpace} creation
     * and shall be treated like a final field from that point.</p>
     */
    private transient WeakValueHashMap<String,Object> childs;

    /**
     * Creates the global namespace. This constructor can be invoked by {@link GlobalNameSpace} only.
     */
    DefaultNameSpace() {
        this.parent        = null;
        this.name          = "global";
        this.headSeparator = DEFAULT_SEPARATOR_STRING;
        this.separator     = DEFAULT_SEPARATOR_STRING;
        init();
    }

    /**
     * Creates a new namespace with the given separator.
     *
     * @param parent
     *          the parent namespace, or {@code null} if none.
     * @param name
     *          the name of the new namespace, usually as a {@link String}
     *          or an {@link InternationalString}.
     * @param headSeparator
     *          the separator to insert between the namespace and the
     *          {@linkplain AbstractName#head() head} of any name in that namespace.
     * @param separator
     *          the separator to insert between the {@linkplain AbstractName#getParsedNames()
     *          parsed names} of any name in that namespace.
     */
    protected DefaultNameSpace(final DefaultNameSpace parent, final CharSequence name,
                               final String headSeparator, final String separator)
    {
        this.parent = (parent != GlobalNameSpace.GLOBAL) ? parent : null;
        ensureNonNull("name",          name);
        ensureNonNull("headSeparator", headSeparator);
        ensureNonNull("separator",     separator);
        this.name          = simplify(name);
        this.headSeparator = headSeparator;
        this.separator     = separator;
        init();
    }

    /**
     * Converts the given name to its {@link String} representation if that name is not an {@link InternationalString}
     * instance from which this {@code DefaultNameSpace} implementation can extract useful information. For example if
     * the given name is a {@link SimpleInternationalString}, that international string does not give more information
     * than the {@code String} that it wraps. Using the {@code String} as the canonical value increase the chances that
     * {@link #equals(Object)} detect that two {@code GenericName} instances are equal.
     */
    private static CharSequence simplify(CharSequence name) {
        if (!(name instanceof InternationalString) || name.getClass() == SimpleInternationalString.class) {
            name = name.toString();
        }
        return name;
    }

    /**
     * Initializes the transient fields.
     */
    private void init() {
        childs = new WeakValueHashMap<>(String.class);
    }

    /**
     * Wraps the given namespace in a {@code DefaultNameSpace} implementation.
     * This method returns an existing instance when possible.
     *
     * @param  ns  the namespace to wrap, or {@code null} for the global one.
     * @return the given namespace as a {@code DefaultNameSpace} implementation.
     */
    static DefaultNameSpace castOrCopy(final NameSpace ns) {
        if (ns == null) {
            return GlobalNameSpace.GLOBAL;
        }
        if (ns instanceof DefaultNameSpace) {
            return (DefaultNameSpace) ns;
        }
        return forName(ns.name(), DEFAULT_SEPARATOR_STRING, DEFAULT_SEPARATOR_STRING);
    }

    /**
     * Returns a namespace having the given name and separators.
     * This method returns an existing instance when possible.
     *
     * @param name
     *          the name for the namespace to obtain, or {@code null}.
     * @param headSeparator
     *          the separator to insert between the namespace and the
     *          {@linkplain AbstractName#head() head} of any name in that namespace.
     * @param separator
     *          the separator to insert between the {@linkplain AbstractName#getParsedNames()
     *          parsed names} of any name in that namespace.
     * @return a namespace having the given name, or {@code null} if name was null.
     */
    static DefaultNameSpace forName(final GenericName name, final String headSeparator, final String separator) {
        if (name == null) {
            return null;
        }
        final List<? extends LocalName> parsedNames = name.getParsedNames();
        final ListIterator<? extends LocalName> it = parsedNames.listIterator(parsedNames.size());
        NameSpace scope;
        /*
         * Searches for the last parsed name having a DefaultNameSpace implementation as its
         * scope. It should be the tip in most cases. If we don't find any, we will recreate
         * the whole chain starting with the global scope.
         */
        do {
            if (!it.hasPrevious()) {
                scope = GlobalNameSpace.GLOBAL;
                break;
            }
            scope = it.previous().scope();
        } while (!(scope instanceof DefaultNameSpace));
        /*
         * We have found a scope. Adds to it the supplemental names.
         * In most cases we should have only the tip to add.
         */
        DefaultNameSpace ns = (DefaultNameSpace) scope;
        while (it.hasNext()) {
            final LocalName tip = it.next();
            ns = ns.child(tip.toString(), tip.toInternationalString(), headSeparator, separator);
        }
        return ns;
    }

    /**
     * Indicates whether this namespace is a "top level" namespace.  Global, or top-level
     * namespaces are not contained within another namespace. The global namespace has no
     * parent.
     *
     * @return {@code true} if this namespace is the global namespace.
     */
    @Override
    public boolean isGlobal() {
        return false;               // To be overridden by GlobalNameSpace.
    }

    /**
     * Returns the parent namespace, replacing null parent by {@link GlobalNameSpace#GLOBAL}.
     */
    final DefaultNameSpace parent() {
        return (parent != null) ? parent : GlobalNameSpace.GLOBAL;
    }

    /**
     * Returns the depth of the given namespace.
     *
     * @param  ns  the namespace for which to get the depth, or {@code null}.
     * @return the depth of the given namespace.
     */
    private static int depth(DefaultNameSpace ns) {
        int depth = 0;
        if (ns != null) do {
            depth++;
            ns = ns.parent;
        } while (ns != null && !ns.isGlobal());
        return depth;
    }

    /**
     * Represents the identifier of this namespace. Namespace identifiers shall be
     * {@linkplain AbstractName#toFullyQualifiedName() fully-qualified names} where
     * the following condition holds:
     *
     * {@preformat java
     *     assert name.scope().isGlobal() == true;
     * }
     *
     * @return the identifier of this namespace.
     */
    @Override
    public GenericName name() {
        final int depth;
        synchronized (this) {
            if (path != null) {
                return path;
            }
            depth = depth(this);
            final DefaultLocalName[] names = new DefaultLocalName[depth];
            DefaultNameSpace scan = this;
            for (int i=depth; --i>=0;) {
                names[i] = new DefaultLocalName(scan.parent, scan.name);
                scan = scan.parent;
            }
            assert depth(scan) == 0 || scan.isGlobal();
            path = DefaultScopedName.create(UnmodifiableArrayList.wrap(names));
            GenericName truncated = path;
            for (int i=depth; --i>=0;) {
                names[i].fullyQualified = truncated;
                truncated = (truncated instanceof ScopedName) ? ((ScopedName) truncated).path() : null;
            }
        }
        /*
         * At this point the name is created and ready to be returned. As an optimization,
         * defines the name of parents now in order to share subarea of the array we just
         * created. The goal is to have less objects in memory.
         */
        AbstractName truncated = path;
        DefaultNameSpace scan = parent;
        while (scan != null && !scan.isGlobal()) {
            /*
             * If we have a parent, then depth >= 2 and consequently the name is a ScopedName.
             * Actually it should be an instance of DefaultScopedName - we known that since we
             * created it ourself with the DefaultScopedName.create(...) method call - and we
             * know that its tail() implementation creates instance of AbstractName. Given all
             * the above, none of the casts on the line below should ever fails, unless there
             * is bug in this package.
             */
            truncated = (AbstractName) ((ScopedName) truncated).path();
            synchronized (scan) {
                if (scan.path == null || scan.path.arraySize() < depth) {
                    scan.path = truncated;
                }
            }
            scan = scan.parent;
        }
        return path;
    }

    /**
     * Returns a child namespace of the given name. The returned namespace will
     * have this namespace as its parent, and will use the same separator.
     *
     * <p>The {@link #headSeparator} is not inherited by the children on intent, because this
     * method is used only by {@link DefaultScopedName} constructors in order to create a
     * sequence of parsed local names. For example in {@code "http://www.opengeospatial.org"}
     * the head separator is {@code "://"} for {@code "www"} (which is having this namespace),
     * but it is {@code "."} for all children ({@code "opengeospatial"} and {@code "org"}).</p>
     *
     * @param  name  the name of the child namespace.
     * @param  sep   the separator to use (typically {@link #separator}).
     * @return the child namespace. It may be an existing instance.
     */
    final DefaultNameSpace child(final CharSequence name, final String sep) {
        return child(key(name), name, sep, sep);
    }

    /**
     * Returns a key to be used in the {@linkplain #childs} pool from the given name.
     * The key must be the unlocalized version of the given string.
     *
     * @param  name  the name.
     * @return a key from the given name.
     */
    private static String key(final CharSequence name) {
        return (name instanceof InternationalString) ?
                ((InternationalString) name).toString(Locale.ROOT) : name.toString();
    }

    /**
     * Returns a child namespace of the given name and separator.
     * The returned namespace will have this namespace as its parent.
     *
     * @param key
     *          the unlocalized name of the child namespace, to be used as a key in the cache.
     * @param name
     *          the name of the child namespace, or {@code null} if same than key.
     * @param headSeparator
     *          the separator to insert between the namespace and the
     *          {@linkplain AbstractName#head() head} of any name in that namespace.
     * @param separator
     *          the separator to insert between the {@linkplain AbstractName#getParsedNames()
     *          parsed names} of any name in that namespace.
     * @return the child namespace. It may be an existing instance.
     */
    private DefaultNameSpace child(final String key, CharSequence name,
            final String headSeparator, final String separator)
    {
        ensureNonNull("key", key);
        if (name == null) {
            name = key;
        } else {
            name = simplify(name);
        }
        final WeakValueHashMap<String,Object> childs = this.childs;     // Paranoiac protection against accidental changes.
        DefaultNameSpace child;
        synchronized (childs) {
            final Object existing = childs.get(key);
            if (existing instanceof DefaultNameSpace) {
                child = (DefaultNameSpace) existing;
                if (!child.separator    .equals(separator) ||
                    !child.headSeparator.equals(headSeparator) ||
                    !child.name         .equals(name))                  // Same test than equalsIgnoreParent.
                {
                    child = new DefaultNameSpace(this, name, headSeparator, separator);
                    /*
                     * Do not cache that instance. Actually we can't guess if that instance
                     * would be more appropriate for caching purpose than the old one. We
                     * just assume that keeping the oldest one is more conservative.
                     */
                }
            } else {
                child = new DefaultNameSpace(this, name, headSeparator, separator);
                if (childs.put(key, child) != existing) {
                    throw new AssertionError();                         // Paranoiac check.
                }
            }
        }
        assert child.parent() == this;
        return child;
    }

    /**
     * Returns a name which is local in this namespace. The returned name will have this
     * namespace as its {@linkplain DefaultLocalName#scope() scope}. This method may returns
     * an existing instance on a "best effort" basis, but this is not guaranteed.
     *
     * @param  name       the name of the instance to create.
     * @param  candidate  the instance to cache if no instance was found for the given name, or {@code null} if none.
     * @return a name which is local in this namespace.
     */
    final DefaultLocalName local(final CharSequence name, final DefaultLocalName candidate) {
        ensureNonNull("name", name);
        final String key = name.toString();
        final WeakValueHashMap<String,Object> childs = this.childs;     // Paranoiac protection against accidental changes.
        DefaultLocalName child;
        synchronized (childs) {
            final Object existing = childs.get(key);
            if (existing instanceof DefaultLocalName) {
                child = (DefaultLocalName) existing;
                if (simplify(name).equals(child.name)) {
                    assert (child.scope != null ? child.scope : GlobalNameSpace.GLOBAL) == this;
                    return child;
                }
            }
            if (candidate != null) {
                child = candidate;
            } else {
                child = new DefaultLocalName(this, name);
            }
            // Cache only if the slot is not already occupied by a NameSpace.
            if (!(existing instanceof DefaultNameSpace)) {
                if (childs.put(key, child) != existing) {
                    throw new AssertionError();                         // Paranoiac check.
                }
            }
        }
        return child;
    }

    /**
     * Returns a JCR-like lexical form representation of this namespace.
     * Following the <cite>Java Content Repository</cite> (JCR) convention,
     * this method returns the string representation of {@linkplain #name()} between curly brackets.
     *
     * <div class="note"><b>Example:</b> if the name of this namespace is “<code>org.apache.sis</code>”,
     * then this method returns “<code>{org.apache.sis}</code>”.</div>
     *
     * <div class="section">Usage</div>
     * With this convention, it would be possible to create an <cite>expanded form</cite> of a generic name
     * (except for escaping of illegal characters) with a simple concatenation as in the following code example:
     *
     * {@preformat java
     *     GenericName name = ...; // A name
     *     println("Expanded form = " + name.scope() + name);
     * }
     *
     * However the convention followed by this {@code DefaultNameSpace} implementation is not specified in the
     * {@link NameSpace} contract. This implementation follows the JCR convention for debugging convenience,
     * but applications needing better guarantees should use {@link Names#toExpandedString(GenericName)} instead.
     *
     * @return a JCR-like lexical form of this namespace.
     *
     * @see Names#toExpandedString(GenericName)
     */
    @Override
    public String toString() {
        return new StringBuilder(name.length() + 2).append('{').append(name).append('}').toString();
    }

    /**
     * Returns {@code true} if this namespace is equal to the given object.
     *
     * @param  object  the object to compare with this namespace.
     * @return {@code true} if the given object is equal to this namespace.
     */
    @Override
    public boolean equals(final Object object) {
        if (object != null && object.getClass() == getClass()) {
            final DefaultNameSpace that = (DefaultNameSpace) object;
            return equalsIgnoreParent(that) && Objects.equals(this.parent, that.parent);
        }
        return false;
    }

    /**
     * Returns {@code true} if the namespace is equal to the given one, ignoring the parent.
     *
     * @param  that  the namespace to compare with this one.
     * @return {@code true} if both namespaces are equal, ignoring the parent.
     */
    private boolean equalsIgnoreParent(final DefaultNameSpace that) {
        return Objects.equals(this.headSeparator, that.headSeparator) &&
               Objects.equals(this.separator,     that.separator) &&
               Objects.equals(this.name,          that.name);               // Most expensive test last.
    }

    /**
     * Returns a hash code value for this namespace.
     */
    @Override
    public int hashCode() {
        return Objects.hash(parent, name, separator);
    }

    /**
     * If an instance already exists for the deserialized namespace, returns that instance.
     * Otherwise completes the initialization of the deserialized instance.
     *
     * <p>Because of its package-private access, this method is <strong>not</strong> invoked if
     * the deserialized class is a subclass defined in an other package. This is the intended
     * behavior since we don't want to replace an instance of a user-defined class.</p>
     *
     * @return the unique instance.
     * @throws ObjectStreamException required by specification but should never be thrown.
     */
    Object readResolve() throws ObjectStreamException {
        final DefaultNameSpace p = parent();
        final String key = key(name);
        final WeakValueHashMap<String,Object> pool = p.childs;
        synchronized (pool) {
            final Object existing = pool.get(key);
            if (existing instanceof DefaultNameSpace) {
                if (equalsIgnoreParent((DefaultNameSpace) existing)) {
                    return existing;
                } else {
                    // Exit from the synchronized block.
                }
            } else {
                init();
                if (pool.put(key, this) != existing) {
                    throw new AssertionError();             // Paranoiac check.
                }
                return this;
            }
        }
        init();
        return this;
    }
}
