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

import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.FileNotFoundException;
import org.opengis.util.NameFactory;
import org.opengis.util.FactoryException;
import org.opengis.referencing.crs.CRSFactory;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.cs.CSFactory;
import org.opengis.referencing.cs.CSAuthorityFactory;
import org.opengis.referencing.datum.DatumFactory;
import org.opengis.referencing.datum.DatumAuthorityFactory;
import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
import org.opengis.referencing.operation.MathTransformFactory;
import org.apache.sis.internal.metadata.sql.Initializer;
import org.apache.sis.internal.referencing.DeferredCoordinateOperation;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.Constants;
import org.apache.sis.referencing.factory.ConcurrentAuthorityFactory;
import org.apache.sis.referencing.factory.UnavailableFactoryException;
import org.apache.sis.util.resources.Messages;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.Classes;
import org.apache.sis.util.Exceptions;
import org.apache.sis.util.Localized;


/**
 * A geodetic object factory backed by the EPSG database. This class creates JDBC connections to the EPSG database
 * when first needed using the {@link DataSource} specified at construction time. The geodetic objects are cached
 * for reuse and the idle connections are closed after a timeout.
 *
 * <p>If no data source has been specified to the constructor, then {@code EPSGFactory} searches for a
 * default data source in JNDI, or in the directory given by the {@code SIS_DATA} environment variable,
 * or in the directory given by the {@code "derby​.system​.home"} property, in that order.
 * See the {@linkplain org.apache.sis.referencing.factory.sql package documentation} for more information.</p>
 *
 * <h2>EPSG dataset installation</h2>
 * This class tries to automatically detect the schema that contains the EPSG tables
 * (see {@link SQLTranslator} for examples of tables to look for). If the tables are not found,
 * then the {@link #install(Connection)} method will be invoked for creating the EPSG schema.
 * The {@code install(…)} method can perform its work only if the definition files are reachable
 * on the classpath, or if the directory containing the files have been specified.
 *
 * <h2>Data Access Object (DAO)</h2>
 * If there is no cached object for a given code, then {@code EPSGFactory} creates an {@link EPSGDataAccess} instance
 * for performing the actual creation work. Developers who need to customize the geodetic object creation can override
 * the {@link #newDataAccess(Connection, SQLTranslator)} method in order to return their own {@link EPSGDataAccess}
 * subclass.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 *
 * @see EPSGDataAccess
 * @see SQLTranslator
 * @see <a href="http://sis.apache.org/tables/CoordinateReferenceSystems.html">List of authority codes</a>
 *
 * @since 0.7
 * @module
 */
public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess> implements CRSAuthorityFactory,
        CSAuthorityFactory, DatumAuthorityFactory, CoordinateOperationAuthorityFactory, Localized
{
    /**
     * The namespace of EPSG codes.
     *
     * @see #getCodeSpaces()
     */
    private static final Set<String> CODESPACES = Collections.singleton(Constants.EPSG);

    /**
     * The factory to use for creating {@link Connection}s to the EPSG database.
     */
    protected final DataSource dataSource;

    /**
     * The factory to use for creating {@link org.opengis.util.GenericName} instances.
     */
    protected final NameFactory nameFactory;

    /**
     * The factory to use for creating {@link org.opengis.referencing.datum.Datum} instances
     * from the properties read in the database.
     */
    protected final DatumFactory datumFactory;

    /**
     * The factory to use for creating {@link org.opengis.referencing.cs.CoordinateSystem} instances
     * from the properties read in the database.
     */
    protected final CSFactory csFactory;

    /**
     * The factory to use for creating {@link org.opengis.referencing.crs.CoordinateReferenceSystem} instances
     * from the properties read in the database.
     */
    protected final CRSFactory crsFactory;

    /**
     * The factory to use for creating {@link org.opengis.referencing.operation.CoordinateOperation} instances
     * from the properties read in the database.
     */
    protected final CoordinateOperationFactory copFactory;

    /**
     * The factory to use for creating {@link org.opengis.referencing.operation.MathTransform} instances.
     * The math transforms are created as part of {@link org.opengis.referencing.operation.CoordinateOperation}
     * creation process.
     */
    protected final MathTransformFactory mtFactory;

    /**
     * The name of the catalog that contains the EPSG tables, or {@code null} or an empty string.
     * <ul>
     *   <li>The {@code ""} value retrieves the EPSG schema without a catalog.</li>
     *   <li>The {@code null} value means that the catalog name should not be used to narrow the search.</li>
     * </ul>
     */
    private final String catalog;

    /**
     * The name of the schema that contains the EPSG tables, or {@code null} or an empty string.
     * <ul>
     *   <li>The {@code ""} value retrieves the EPSG tables without a schema.
     *       In such case, table names are prefixed by {@value SQLTranslator#TABLE_PREFIX}.</li>
     *   <li>The {@code null} value means that the schema name should not be used to narrow the search.
     *       In such case, {@link SQLTranslator} will tries to automatically detect the schema.</li>
     * </ul>
     */
    private final String schema;

    /**
     * A provider of SQL scripts to use if {@code EPSGFactory} needs to create the database,
     * or {@code null} for the default mechanism.
     */
    private final InstallationScriptProvider scriptProvider;

    /**
     * The translator from the SQL statements using MS-Access dialect to SQL statements using the dialect
     * of the actual database. If null, will be created when first needed.
     */
    private volatile SQLTranslator translator;

    /**
     * The locale for producing error messages. This is usually the default locale.
     *
     * @see #getLocale()
     */
    private final Locale locale;

    /**
     * Creates a factory using the given configuration. The properties recognized by this constructor
     * are listed in the table below. Any property not listed below will be ignored by this constructor.
     * All properties are optional and can {@code null} or omitted, in which case default values are used.
     * Those default values are implementation-specific and may change in any future SIS version.
     *
     * <table class="sis">
     *  <caption>Recognized properties</caption>
     *  <tr>
     *   <th>Key</th>
     *   <th>Value class</th>
     *   <th>Description</th>
     *  </tr><tr>
     *   <td>{@code dataSource}</td>
     *   <td>{@link DataSource}</td>
     *   <td>The factory to use for creating {@link Connection}s to the EPSG database.</td>
     *  </tr><tr>
     *   <td>{@code nameFactory}</td>
     *   <td>{@link NameFactory}</td>
     *   <td>The factory to use for creating {@link org.opengis.util.GenericName} instances.</td>
     *  </tr><tr>
     *   <td>{@code datumFactory}</td>
     *   <td>{@link DatumAuthorityFactory}</td>
     *   <td>The factory to use for creating {@link org.opengis.referencing.datum.Datum} instances.</td>
     *  </tr><tr>
     *   <td>{@code csFactory}</td>
     *   <td>{@link CSAuthorityFactory}</td>
     *   <td>The factory to use for creating {@link org.opengis.referencing.cs.CoordinateSystem} instances.</td>
     *  </tr><tr>
     *   <td>{@code crsFactory}</td>
     *   <td>{@link CRSAuthorityFactory}</td>
     *   <td>The factory to use for creating {@link org.opengis.referencing.crs.CoordinateReferenceSystem} instances.</td>
     *  </tr><tr>
     *   <td>{@code copFactory}</td>
     *   <td>{@link CoordinateOperationAuthorityFactory}</td>
     *   <td>The factory to use for creating {@link org.opengis.referencing.operation.CoordinateOperation} instances.</td>
     *  </tr><tr>
     *   <td>{@code mtFactory}</td>
     *   <td>{@link MathTransformFactory}</td>
     *   <td>The factory to use for creating {@link org.opengis.referencing.operation.MathTransform} instances.</td>
     *  </tr><tr>
     *   <td>{@code catalog}</td>
     *   <td>{@link String}</td>
     *   <td>The database catalog that contains the EPSG schema (see {@linkplain #install install}).</td>
     *  </tr><tr>
     *   <td>{@code schema}</td>
     *   <td>{@link String}</td>
     *   <td>The database schema that contains the EPSG tables (see {@linkplain #install install}).</td>
     *  </tr><tr>
     *   <td>{@code scriptProvider}</td>
     *   <td>{@link InstallationScriptProvider}</td>
     *   <td>A provider of SQL scripts to use if {@code EPSGFactory} needs to create the database.</td>
     *  </tr><tr>
     *   <td>{@code locale}</td>
     *   <td>{@link Locale}</td>
     *   <td>The locale for producing error messages on a <cite>best effort</cite> basis.</td>
     *  </tr>
     * </table>
     *
     * <p>Default values</p>
     * <ul>
     *   <li>If no {@code dataSource} is specified, this constructor defaults to the search algorithm described
     *       in the {@linkplain org.apache.sis.referencing.factory.sql package documentation}.</li>
     *   <li>If no {@code catalog} or {@code schema} is specified, {@link SQLTranslator} will try to auto-detect
     *       the schema that contains the EPSG tables.</li>
     *   <li>If no {@code locale} is specified, this constructor defaults to the
     *       {@linkplain Locale#getDefault(Locale.Category) display locale}.</li>
     * </ul>
     *
     * @param  properties  the data source, authority factories and other configuration properties,
     *                     or {@code null} for the default values.
     * @throws ClassCastException if a property value is not of the expected class.
     * @throws IllegalArgumentException if a property value is invalid.
     * @throws FactoryException if an error occurred while creating the EPSG factory.
     */
    public EPSGFactory(Map<String,?> properties) throws FactoryException {
        super(EPSGDataAccess.class);
        if (properties == null) {
            properties = Collections.emptyMap();
        }
        DataSource ds  = (DataSource)                 properties.get("dataSource");
        Locale locale  = (Locale)                     properties.get("locale");
        schema         = (String)                     properties.get("schema");
        catalog        = (String)                     properties.get("catalog");
        scriptProvider = (InstallationScriptProvider) properties.get("scriptProvider");
        if (locale == null) {
            locale = Locale.getDefault(Locale.Category.DISPLAY);
        }
        this.locale = locale;
        if (ds == null) try {
            ds = Initializer.getDataSource();
            if (ds == null) {
                throw new UnavailableFactoryException(String.valueOf(Initializer.unspecified(locale, false)));
            }
        } catch (Exception e) {
            throw new UnavailableFactoryException(canNotUse(e), e);
        }
        dataSource   = ds;
        nameFactory  = factory(NameFactory.class,                "nameFactory",  properties);
        datumFactory = factory(DatumFactory.class,               "datumFactory", properties);
        csFactory    = factory(CSFactory.class,                  "csFactory",    properties);
        crsFactory   = factory(CRSFactory.class,                 "crsFactory",   properties);
        copFactory   = factory(CoordinateOperationFactory.class, "copFactory",   properties);
        mtFactory    = factory(MathTransformFactory.class,       "mtFactory",    properties);
        super.setTimeout(10, TimeUnit.SECONDS);
    }

    /**
     * Returns the factory for the given key if it exists, or the default factory instance otherwise.
     */
    private static <F> F factory(final Class<F> type, final String key, final Map<String,?> properties) {
        final F factory = type.cast(properties.get(key));
        return (factory != null) ? factory : DefaultFactories.forBuildin(type);
    }

    /**
     * Returns the message to put in an {@link UnavailableFactoryException} having the given exception as its cause.
     */
    private String canNotUse(final Exception e) {
        String message = Exceptions.getLocalizedMessage(e, locale);
        if (message == null) {
            message = Classes.getShortClassName(e);
        }
        return canNotUse(message);
    }

    /**
     * Returns the message to put in an {@link UnavailableFactoryException} having the given cause.
     */
    private String canNotUse(final String cause) {
        return Resources.forLocale(locale).getString(Resources.Keys.CanNotUseGeodeticParameters_2, Constants.EPSG, cause);
    }

    /**
     * Returns the namespace of EPSG codes.
     *
     * @return the {@code "EPSG"} string in a singleton map.
     */
    @Override
    public Set<String> getCodeSpaces() {
        return CODESPACES;
    }

    /**
     * Returns the locale used by this factory for producing error messages.
     * This locale does not change the way data are read from the EPSG database.
     *
     * @return the locale for error messages.
     */
    @Override
    public Locale getLocale() {
        return locale;
    }

    /**
     * Creates the EPSG schema in the database and populates the tables with geodetic definitions.
     * This method is invoked automatically when {@link #newDataAccess()} detects that the EPSG dataset is not installed.
     * Users can also invoke this method explicitly if they wish to force the dataset installation.
     *
     * <p>This method uses the following properties from the map specified at
     * {@linkplain #EPSGFactory(Map) construction time}:</p>
     *
     * <ul class="verbose">
     *   <li><b>{@code catalog}:</b><br>
     *     a {@link String} giving the name of the database catalog where to create the EPSG schema.
     *     If non-null, that catalog shall exist prior this method call (this method does not create any catalog).
     *     If no catalog is specified or if the catalog is an empty string,
     *     then the EPSG schema will be created without catalog.
     *     If the database does not {@linkplain DatabaseMetaData#supportsCatalogsInTableDefinitions() support
     *     catalogs in table definitions} or in {@linkplain DatabaseMetaData#supportsCatalogsInDataManipulation()
     *     data manipulation}, then this property is ignored.</li>
     *
     *   <li><b>{@code schema}:</b><br>
     *     a {@link String} giving the name of the database schema where to create the EPSG tables.
     *     That schema shall <strong>not</strong> exist prior this method call;
     *     the schema will be created by this {@code install(…)} method.
     *     If the schema is an empty string, then the tables will be created without schema.
     *     If no schema is specified, then the default schema is {@code "EPSG"}.
     *     If the database does not {@linkplain DatabaseMetaData#supportsSchemasInTableDefinitions() support
     *     schemas in table definitions} or in {@linkplain DatabaseMetaData#supportsSchemasInDataManipulation()
     *     data manipulation}, then this property is ignored.</li>
     *
     *   <li><b>{@code scriptProvider}:</b><br>
     *     an {@link InstallationScriptProvider} giving the SQL scripts to execute for creating the EPSG database.
     *     If no provider is specified, then this method will search on the classpath (with {@link java.util.ServiceLoader})
     *     for user-provided implementations of {@code InstallationScriptProvider}.
     *     If no user-specified provider is found, then this method will search for
     *     {@code "EPSG_*Tables.sql"}, {@code "EPSG_*Data.sql"} and {@code "EPSG_*FKeys.sql"} files in the
     *     {@code $SIS_DATA/Databases/ExternalSources} directory where {@code *} stands for any characters
     *     provided that there is no ambiguity.</li>
     * </ul>
     *
     * <p><b>Legal constraint:</b>
     * the EPSG dataset can not be distributed with Apache SIS at this time for licensing reasons.
     * Users need to either install the dataset manually (for example with the help of this method),
     * or add on the classpath to a separated bundle like {@code org.apache.sis:non-free:sis-epsg.jar}.
     * See <a href="http://sis.apache.org/epsg.html">How to use EPSG geodetic dataset</a> for more information.</p>
     *
     * @param  connection  connection to the database where to create the EPSG schema.
     * @throws UnavailableFactoryException if installation failed. The exception will have a
     *         {@link FileNotFoundException} cause if a SQL script has not been found
     *         (typically because a required resource is not on the classpath), an
     *         {@link IOException} if an I/O error occurred while reading a SQL script, or a
     *         {@link SQLException} if an error occurred while writing to the database.
     *
     * @see InstallationScriptProvider
     */
    public synchronized void install(final Connection connection) throws UnavailableFactoryException {
        ArgumentChecks.ensureNonNull("connection", connection);
        String    message = null;
        Exception failure = null;
        try (EPSGInstaller installer = new EPSGInstaller(connection)) {
            final boolean ac = connection.getAutoCommit();
            if (ac) {
                connection.setAutoCommit(false);
            }
            try {
                boolean success = false;
                try {
                    if (!"".equals(schema)) {                                           // Schema may be null.
                        installer.setSchema(schema != null ? schema : Constants.EPSG);
                        if (catalog != null && !catalog.isEmpty()) {
                            installer.prependNamespace(catalog);
                        }
                    }
                    installer.run(scriptProvider, locale);
                    success = true;
                } finally {
                    if (ac) {
                        if (success) {
                            connection.commit();
                        } else {
                            connection.rollback();
                        }
                        connection.setAutoCommit(true);
                    }
                }
            } catch (IOException | SQLException e) {
                message = installer.failure(locale, e);
                failure = e;
            }
        } catch (SQLException e) {
            message = Messages.getResources(locale).getString(Messages.Keys.CanNotCreateSchema_1, Constants.EPSG);
            failure = e;
        }
        if (failure != null) {
            /*
             * Derby sometime wraps SQLException into another SQLException.  For making the stack strace a
             * little bit simpler, keep only the root cause provided that the exception type is compatible.
             */
            UnavailableFactoryException exception = new UnavailableFactoryException(message, Exceptions.unwrap(failure));
            exception.setUnavailableFactory(this);
            throw exception;
        }
    }

    /**
     * Creates the factory which will perform the actual geodetic object creation work.
     * This method is invoked automatically when a new worker is required, either because the previous
     * one has been disposed after its timeout or because a new one is required for concurrency.
     *
     * <p>The default implementation performs the following steps:</p>
     * <ol>
     *   <li>Gets a new connection from the {@link #dataSource}.</li>
     *   <li>If this method is invoked for the first time, verifies if the EPSG tables exists.
     *       If the tables are not found, invokes {@link #install(Connection)}.</li>
     *   <li>Delegates to {@link #newDataAccess(Connection, SQLTranslator)}, which provides an easier
     *       overriding point for subclasses wanting to return a custom {@link EPSGDataAccess} instance.</li>
     * </ol>
     *
     * @return Data Access Object (DAO) to use in {@code createFoo(String)} methods.
     * @throws FactoryException if the constructor failed to connect to the EPSG database.
     *         This exception usually has a {@link SQLException} as its cause.
     */
    @Override
    protected EPSGDataAccess newDataAccess() throws FactoryException {
        UnavailableFactoryException exception;
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            Logging.log(EPSGFactory.class, "newDataAccess", Initializer.connected(connection.getMetaData()));
            SQLTranslator tr = translator;
            if (tr == null) {
                synchronized (this) {
                    tr = translator;
                    if (tr == null) {
                        tr = new SQLTranslator(connection.getMetaData(), catalog, schema);
                        try {
                            if (!tr.isTableFound()) {
                                install(connection);
                                tr.setup(connection.getMetaData());         // Set only on success.
                            }
                        } finally {
                            translator = tr;        // Set only after installation in order to block other threads.
                        }
                    }
                }
            }
            if (tr.isTableFound()) {
                return newDataAccess(connection, tr);
            } else {
                connection.close();
                exception = new UnavailableFactoryException(canNotUse(SQLTranslator.tableNotFound(locale)));
            }
        } catch (Exception e) {                     // Really want to catch all exceptions here.
            if (connection != null) try {
                connection.close();
            } catch (SQLException e2) {
                e.addSuppressed(e2);
            }
            if (e instanceof FactoryException) {
                throw (FactoryException) e;
            }
            /*
             * Derby sometime wraps SQLException into another SQLException.  For making the stack strace a
             * little bit simpler, keep only the root cause provided that the exception type is compatible.
             */
            exception = new UnavailableFactoryException(canNotUse(e), Exceptions.unwrap(e));
        }
        exception.setUnavailableFactory(this);
        throw exception;
    }

    /**
     * Creates the factory which will perform the actual geodetic object creation from a given connection.
     * This method is a convenience hook easier to override than {@link #newDataAccess()} for subclasses
     * wanting to return instances of their own {@link EPSGDataAccess} subclass.
     * The default implementation is simply:
     *
     * {@preformat java
     *     return new EPSGDataAccess(this, connection, translator);
     * }
     *
     * Subclasses can override this method with a similar code but with {@code new EPSGDataAccess(…)} replaced
     * by {@code new MyDataAccessSubclass(…)}.
     *
     * @param  connection  a connection to the EPSG database.
     * @param  translator  the translator from the SQL statements using MS-Access dialect to SQL statements
     *                     using the dialect of the actual database.
     * @return Data Access Object (DAO) to use in {@code createFoo(String)} methods.
     * @throws SQLException if a problem with the database has been detected.
     *
     * @see EPSGDataAccess#EPSGDataAccess(EPSGFactory, Connection, SQLTranslator)
     */
    protected EPSGDataAccess newDataAccess(Connection connection, SQLTranslator translator) throws SQLException {
        return new EPSGDataAccess(this, connection, translator);
    }

    /**
     * Returns {@code true} if the given Data Access Object (DAO) can be closed. This method is invoked automatically
     * after the {@linkplain #getTimeout timeout} if the given DAO has been idle during all that time. The default
     * implementation always returns {@code false} if a set returned by {@link EPSGDataAccess#getAuthorityCodes(Class)}
     * is still in use.
     *
     * @param  factory  the Data Access Object which is about to be closed.
     * @return {@code true} if the given Data Access Object can be closed.
     */
    @Override
    protected boolean canClose(final EPSGDataAccess factory) {
        return factory.canClose();
    }

    /**
     * Returns whether the given object can be cached.
     * This method is invoked after {@link EPSGDataAccess} created a new object not previously in the cache.
     *
     * @return whether the given object should be cached.
     *
     * @since 0.8
     */
    @Override
    protected boolean isCacheable(String code, Object object) {
        return !(object instanceof DeferredCoordinateOperation);
    }
}
