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

import java.util.Date;
import java.util.Collection;
import java.io.ObjectStreamException;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.citation.CitationDate;
import org.opengis.metadata.citation.OnlineResource;
import org.opengis.metadata.citation.PresentationForm;
import org.opengis.metadata.citation.ResponsibleParty;
import org.opengis.metadata.citation.Series;
import org.opengis.metadata.identification.BrowseGraphic;
import org.opengis.util.InternationalString;
import org.apache.sis.xml.IdentifierSpace;
import org.apache.sis.metadata.sql.MetadataSource;
import org.apache.sis.metadata.sql.MetadataStoreException;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.internal.system.Loggers;
import org.apache.sis.internal.util.Strings;
import org.apache.sis.util.logging.Logging;


/**
 * Base class for the {@code public static final Citation} constants defined in some SIS classes.
 * This base class contains only an abbreviation (e.g. {@code "OGC"} or {@code "EPSG"}) which can
 * be used as the primary key where to search for more information in a database. If no database
 * is available, then that simple primary key will be used as the citation title.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 *
 * @see IdentifierSpace
 * @see Citations
 *
 * @since 0.6
 * @module
 */
public class CitationConstant extends SimpleCitation {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -8429121584437634107L;

    /**
     * Class of {@code public static final Citation} constants which are also used as namespace for identifiers.
     * The most typical example is the "EPSG" authority which manage the codes identifying Coordinate Reference
     * System (CRS) objects in the EPSG namespace.
     *
     * @param <T>  the type of object used as identifier values.
     */
    public static class Authority<T> extends CitationConstant implements IdentifierSpace<T> {
        /**
         * For cross-version compatibility.
         */
        private static final long serialVersionUID = 2067932813561130294L;

        /**
         * Creates a new citation for an authority managing codes in the given namespace.
         * This constructor assumes that the namespace is the same as the abbreviation given as citation title.
         *
         * @param  namespace  the namespace of codes managed by this authority (e.g. "EPSG").
         */
        public Authority(final String namespace) {
            super(namespace);
        }

        /**
         * Creates a new citation for an authority managing codes in the given namespace.
         *
         * @param  name       a human-understandable primary key for fetching more information.
         * @param  namespace  the namespace of codes managed by this authority (e.g. "EPSG").
         */
        public Authority(final String name, final String namespace) {
            super(name, namespace);
        }

        /**
         * Returns the name space given at construction time. Can be one of the following:
         * <ul>
         *   <li>Abbreviation of the authority managing the codes (e.g. {@code "EPSG"} or {@code "ISBN"}).</li>
         *   <li>XML attribute name with its prefix (e.g. {@code "gml:id"}, {@code "gco:uuid"} or {@code "xlink:href"}).</li>
         * </ul>
         */
        @Override
        public final String getName() {
            return namespace;
        }

        /**
         * Returns a string representation of this identifier space.
         */
        @Override
        public final String toString() {
            return Strings.bracket(IdentifierSpace.class, title);
        }
    }

    /**
     * The name by which this citation is known to {@link Citations#fromName(String)}.
     * Often the same than the abbreviation that {@link CitationConstant} uses as the title.
     * If this {@code CitationConstant} is a {@link Authority} subtype, then this is also
     * the authority namespace.
     */
    public final String namespace;

    /**
     * The citation which contain the "real" data, or {@code null} if not yet created.
     * This is usually an instance created by {@link MetadataSource}. Those instances
     * manage their own caching, so accesses to the database should not occur often.
     */
    private transient volatile Citation delegate;

    /**
     * Creates a new proxy for the given primary key.
     * The key should be readable enough for being usable as a fallback if the database is not available.
     *
     * @param  name  a human-understandable primary key for fetching more information.
     */
    public CitationConstant(final String name) {
        super(name);
        this.namespace = name;
    }

    /**
     * Creates a new proxy for the given primary key but a different programmatic name.
     * The key should be readable enough for being usable as a fallback if the database is not available.
     *
     * @param  name       a human-understandable primary key for fetching more information.
     * @param  namespace  the name by which this citation is known to {@link Citations#fromName(String)}.
     */
    public CitationConstant(final String name, final String namespace) {
        super(name);
        this.namespace = namespace;
    }

    /**
     * Notify this instance that the database content may have changed, or that the classpath has changed.
     */
    public final void refresh() {
        delegate = null;
    }

    /**
     * Returns the citation instance which contain the actual data. That instance is provided by the
     * {@code sis-metadata} module, which is optional.  If that module is not on the classpath, then
     * this {@code delegate()} method will use the few information provided by the current instance.
     *
     * <p>Note that it should be very rare to not have {@code sis-metadata} on the classpath,
     * since that module is required by {@code sis-referencing} which is itself required by
     * almost all other SIS modules.</p>
     */
    @SuppressWarnings("DoubleCheckedLocking")
    private Citation delegate() {
        Citation c = delegate;
        if (c == null) {
            synchronized (this) {
                c = delegate;
                if (c == null) {
                    try {
                        c = MetadataSource.getProvided().lookup(Citation.class, title);
                    } catch (MetadataStoreException e) {
                        /*
                         * If no database was available, MetadataSource.getProvided() was supposed to fallback on
                         * the MetadataFallback class. So if we get this exception, a more serious error occurred.
                         * It is still not fatal however, since most of Citation content is informative.
                         */
                        Logging.unexpectedException(Logging.getLogger(Loggers.SQL), CitationConstant.class, "delegate", e);
                        c = new SimpleCitation(title);
                    }
                    delegate = c;
                }
            }
        }
        return c;
    }

    /**
     * Redirects the call to the delegate citation (the instance which actually contain the data).
     *
     * @return the value returned by the delegate.
     */
    @Override public InternationalString                        getTitle()                   {return delegate().getTitle();}
    @Override public Collection<? extends InternationalString>  getAlternateTitles()         {return delegate().getAlternateTitles();}
    @Override public Collection<? extends CitationDate>         getDates()                   {return delegate().getDates();}
    @Override public InternationalString                        getEdition()                 {return delegate().getEdition();}
    @Override public Date                                       getEditionDate()             {return delegate().getEditionDate();}
    @Override public Collection<? extends Identifier>           getIdentifiers()             {return delegate().getIdentifiers();}
    @Override public Collection<? extends ResponsibleParty>     getCitedResponsibleParties() {return delegate().getCitedResponsibleParties();}
    @Override public Collection<PresentationForm>               getPresentationForms()       {return delegate().getPresentationForms();}
    @Override public Series                                     getSeries()                  {return delegate().getSeries();}
    @Override public InternationalString                        getOtherCitationDetails()    {return delegate().getOtherCitationDetails();}
    @Override public Collection<? extends OnlineResource>       getOnlineResources()         {return delegate().getOnlineResources();}
    @Override public Collection<? extends BrowseGraphic>        getGraphics()                {return delegate().getGraphics();}
    @Override public String                                     getISBN()                    {return delegate().getISBN();}
    @Override public String                                     getISSN()                    {return delegate().getISSN();}

    /**
     * Invoked at deserialization time in order to replace the deserialized instance by the existing
     * instance defined in the {@link org.apache.sis.metadata.iso.citation.Citations} class.
     *
     * @return the instance to use, as an unique instance if possible.
     * @throws ObjectStreamException never thrown.
     */
    protected Object readResolve() throws ObjectStreamException {
        final Citation c = Citations.fromName(title);
        return (c instanceof CitationConstant) ? c : this;
        /*
         * Returns 'this' should happen only if the Citation has been serialized
         * on a more recent version of Apache SIS than the current version.
         */
    }
}
