/*
 * 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.Set;
import java.util.Locale;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.sql.Connection;
import java.io.BufferedReader;
import java.io.LineNumberReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.setup.InstallationResources;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.internal.referencing.Fallback;
import org.apache.sis.internal.system.DataDirectory;
import org.apache.sis.internal.system.Loggers;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.util.Constants;


/**
 * Provides SQL scripts needed for creating a local copy of a dataset. This class allows Apache SIS users
 * to bundle the EPSG or other datasets in their own product for automatic installation when first needed.
 * Implementations of this class can be declared in the following file for automatic discovery by {@link EPSGFactory}:
 *
 * {@preformat text
 *     META-INF/services/org.apache.sis.setup.InstallationResources
 * }
 *
 * <h2>How this class is used</h2>
 * The first time that an {@link EPSGDataAccess} needs to be instantiated,
 * {@link EPSGFactory} verifies if the EPSG database exists. If it does not, then:
 * <ol>
 *   <li>{@link EPSGFactory#install(Connection)} searches for the first instance of {@link InstallationResources}
 *       (the parent of this class) for which the {@linkplain #getAuthorities() set of authorities} contains {@code "EPSG"}.</li>
 *   <li>The {@linkplain #getLicense license} may be shown to the user if the application allows that
 *       (for example when running as a {@linkplain org.apache.sis.console console application}).</li>
 *   <li>If the installation process is allowed to continue, it will iterate over all readers provided by
 *       {@link #openScript(String, int)} and execute the SQL statements (not necessarily verbatim;
 *       the installation process may adapt to the target database).</li>
 * </ol>
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.7
 * @since   0.7
 * @module
 */
public abstract class InstallationScriptProvider extends InstallationResources {
    /**
     * A sentinel value for the content of the script to execute before the SQL scripts provided by the authority.
     * This is an Apache SIS build-in script for constraining the values of some {@code VARCHAR} columns
     * to enumerations of values recognized by {@link EPSGDataAccess}. Those enumerations are not required
     * for proper working of {@link EPSGFactory}, but can improve data integrity.
     */
    protected static final String PREPARE = "Prepare";

    /**
     * A sentinel value for the content of the script to execute after the SQL scripts provided by the authority.
     * This is an Apache SIS build-in script for creating indexes or performing any other manipulation that help
     * SIS to use the dataset. Those indexes are not required for proper working of {@link EPSGFactory},
     * but can significantly improve performances.
     */
    protected static final String FINISH = "Finish";

    /**
     * The authorities to be returned by {@link #getAuthorities()}.
     */
    private final Set<String> authorities;

    /**
     * The names of the SQL scripts to read.
     */
    private final String[] resources;

    /**
     * Creates a new provider which will read script files of the given names in that order.
     * The given names are often filenames, but not necessarily
     * (it is okay to use those names only as labels).
     *
     * <table class="sis">
     *   <caption>Typical argument values</caption>
     *   <tr>
     *     <th>Authority</th>
     *     <th class="sep">Argument values</th>
     *   </tr><tr>
     *     <td>{@code EPSG}</td>
     *     <td class="sep"><code>
     *       {{@linkplain #PREPARE}, "EPSG_Tables.sql", "EPSG_Data.sql", "EPSG_FKeys.sql", {@linkplain #FINISH}}
     *     </code></td>
     *   </tr>
     * </table>
     *
     * @param  authority  the authority (typically {@code "EPSG"}), or {@code null} if not available.
     * @param  resources  names of the SQL scripts to read.
     *
     * @see #getResourceNames(String)
     * @see #openStream(String)
     */
    protected InstallationScriptProvider(final String authority, final String... resources) {
        ArgumentChecks.ensureNonNull("resources", resources);
        authorities = CollectionsExt.singletonOrEmpty(authority);
        this.resources = resources;
    }

    /**
     * Returns the identifiers of the dataset installed by the SQL scripts.
     * The values currently recognized by SIS are:
     *
     * <ul>
     *   <li>{@code "EPSG"} for the EPSG geodetic dataset.</li>
     * </ul>
     *
     * The default implementation returns the authority given at construction time, or an empty set
     * if that authority was {@code null}. An empty set means that the provider does not have all
     * needed resources or does not have permission to distribute the installation scripts.
     *
     * @return identifiers of SQL scripts that this instance can distribute.
     */
    @Override
    @SuppressWarnings("ReturnOfCollectionOrArrayField")
    public Set<String> getAuthorities() {
        return authorities;
    }

    /**
     * Verifies that the given authority is one of the expected values.
     */
    private void verifyAuthority(final String authority) {
        if (!authorities.contains(authority)) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "authority", authority));
        }
    }

    /**
     * Returns the names of all SQL scripts to execute.
     * This is a copy of the array of names given to the constructor.
     * Those names are often filenames, but not necessarily (they may be just labels).
     *
     * @param  authority  the value given at construction time (e.g. {@code "EPSG"}).
     * @return the names of all SQL scripts to execute.
     * @throws IllegalArgumentException if the given {@code authority} argument is not the expected value.
     * @throws IOException if fetching the script names required an I/O operation and that operation failed.
     */
    @Override
    public String[] getResourceNames(String authority) throws IOException {
        verifyAuthority(authority);
        return resources.clone();
    }

    /**
     * Returns a reader for the SQL script at the given index. Contents may be read from files in a local directory,
     * or from resources in a JAR file, or from entries in a ZIP file, or any other means at implementer choice.
     * The {@link BufferedReader} instances shall be closed by the caller.
     *
     * <h4>EPSG case</h4>
     * In the EPSG dataset case, the iterator should return {@code BufferedReader} instances for the following files
     * (replace {@code <version>} by the EPSG version number and {@code <product>} by the target database) in same order.
     * The first and last files are provided by Apache SIS.
     * All other files can be downloaded from <a href="http://www.epsg.org/">http://www.epsg.org/</a>.
     *
     * <ol>
     *   <li>Content of {@link #PREPARE}, an optional data definition script that define the enumerations expected by {@link EPSGDataAccess}.</li>
     *   <li>Content of {@code "EPSG_<version>.mdb_Tables_<product>.sql"}, a data definition script that create empty tables.</li>
     *   <li>Content of {@code "EPSG_<version>.mdb_Data_<product>.sql"}, a data manipulation script that populate the tables.</li>
     *   <li>Content of {@code "EPSG_<version>.mdb_FKeys_<product>.sql"}, a data definition script that create foreigner key constraints.</li>
     *   <li>Content of {@link #FINISH}, an optional data definition and data control script that create indexes and set permissions.</li>
     * </ol>
     *
     * Implementers are free to return a different set of scripts with equivalent content.
     *
     * <h4>Default implementation</h4>
     * The default implementation invokes {@link #openStream(String)} – except for {@link #PREPARE} and {@link #FINISH}
     * in which case an Apache SIS build-in script is used – and wrap the result in a {@link LineNumberReader}.
     * The file encoding is UTF-8 (the encoding used in the scripts distributed by EPSG since version 9.4).
     *
     * @param  authority  the value given at construction time (e.g. {@code "EPSG"}).
     * @param  resource   index of the SQL script to read, from 0 inclusive to
     *         <code>{@linkplain #getResourceNames getResourceNames}(authority).length</code> exclusive.
     * @return a reader for the content of SQL script to execute.
     * @throws IllegalArgumentException if the given {@code authority} argument is not the expected value.
     * @throws IndexOutOfBoundsException if the given {@code resource} argument is out of bounds.
     * @throws FileNotFoundException if the SQL script of the given name has not been found.
     * @throws IOException if an error occurred while creating the reader.
     */
    @Override
    public BufferedReader openScript(final String authority, final int resource) throws IOException {
        verifyAuthority(authority);
        ArgumentChecks.ensureValidIndex(resources.length, resource);
        if (!Constants.EPSG.equals(authority)) {
            throw new IllegalStateException(Resources.format(Resources.Keys.UnknownAuthority_1, authority));
        }
        String name = resources[resource];
        final InputStream in;
        if (PREPARE.equals(name) || FINISH.equals(name)) {
            name = authority + '_' + name + ".sql";
            in = InstallationScriptProvider.class.getResourceAsStream(name);
        } else {
            in = openStream(name);
            name = name.concat(".sql");
        }
        if (in == null) {
            throw new FileNotFoundException(Errors.format(Errors.Keys.FileNotFound_1, name));
        }
        return new LineNumberReader(new InputStreamReader(in, StandardCharsets.UTF_8));
    }

    /**
     * Opens the input stream for the SQL script of the given name.
     * This method is invoked by the default implementation of {@link #openScript(String, int)}
     * for all scripts except {@link #PREPARE} and {@link #FINISH}.
     *
     * <div class="note"><b>Example 1:</b>
     * if this {@code InstallationScriptProvider} instance gets the SQL scripts from files in a well-known directory
     * and if the names given at {@linkplain #InstallationScriptProvider(String, String...) construction time} are the
     * filenames in that directory, then this method can be implemented as below:
     *
     * {@preformat java
     *    protected InputStream openStream(String name) throws IOException {
     *        return Files.newInputStream(directory.resolve(name));
     *    }
     * }
     * </div>
     *
     * <div class="note"><b>Example 2:</b>
     * if this {@code InstallationScriptProvider} instance rather gets the SQL scripts from resources bundled
     * in the same JAR files than and in the same package, then this method can be implemented as below:
     *
     * {@preformat java
     *    protected InputStream openStream(String name) {
     *        return MyClass.getResourceAsStream(name);
     *    }
     * }
     * </div>
     *
     * @param  name  name of the script file to open. Can be {@code null} if the resource is not found.
     * @return an input stream opened of the given script file.
     * @throws IOException if an error occurred while opening the file.
     */
    protected abstract InputStream openStream(final String name) throws IOException;

    /**
     * Logs the given record. This method pretend that the record has been logged by
     * {@code EPSGFactory.install(…)} because it is the public API using this class.
     */
    static void log(final LogRecord record) {
        record.setLoggerName(Loggers.CRS_FACTORY);
        Logging.log(EPSGFactory.class, "install", record);
    }




    /**
     * The default implementation which use the scripts in the {@code $SIS_DATA/Databases/ExternalSources}
     * directory, if present. This class expects the files to have those exact names where {@code *} stands
     * for any characters provided that there is no ambiguity:
     *
     * <ul>
     *   <li>{@code EPSG_*Tables.sql}</li>
     *   <li>{@code EPSG_*Data.sql}</li>
     *   <li>{@code EPSG_*FKeys.sql}</li>
     * </ul>
     *
     * @author  Martin Desruisseaux (Geomatys)
     * @version 0.7
     * @since   0.7
     * @module
     */
    @Fallback
    static final class Default extends InstallationScriptProvider {
        /**
         * The directory containing the scripts, or {@code null} if it does not exist.
         */
        private Path directory;

        /**
         * Index of the first real file in the array given to the constructor.
         * We set the value to 1 for skipping the {@code PREPARE} pseudo-file.
         */
        private static final int FIRST_FILE = 1;

        /**
         * Creates a default provider.
         *
         * @param locale  the locale for warning messages, if any.
         */
        Default(final Locale locale) throws IOException {
            super(Constants.EPSG,
                    PREPARE,
                    "Tables",
                    "Data",
                    "FKeys",
                    FINISH);

            Path dir = DataDirectory.DATABASES.getDirectory();
            if (dir != null) {
                dir = dir.resolve("ExternalSources");
                if (Files.isDirectory(dir)) {
                    final String[] resources = super.resources;
                    final String[] found = new String[resources.length - FIRST_FILE - 1];
                    try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "EPSG_*.sql")) {
                        for (final Path path : stream) {
                            final String name = path.getFileName().toString();
                            for (int i=0; i<found.length; i++) {
                                final String part = resources[FIRST_FILE + i];
                                if (name.contains(part)) {
                                    if (found[i] != null) {
                                        log(Errors.getResources(locale)
                                                  .getLogRecord(Level.WARNING, Errors.Keys.DuplicatedFileReference_1, part));
                                        return;   // Stop the search because of duplicated file.
                                    }
                                    found[i] = name;
                                }
                            }
                        }
                    }
                    for (int i=0; i<found.length; i++) {
                        final String file = found[i];
                        if (file != null) {
                            resources[FIRST_FILE + i] = file;
                        } else {
                            dir = null;
                        }
                    }
                    directory = dir;
                }
            }
        }

        /**
         * Returns {@code "EPSG"} if the scripts exist in the {@code ExternalSources} subdirectory,
         * or {@code "unavailable"} otherwise.
         *
         * @return {@code "EPSG"} if the SQL scripts for installing the EPSG dataset are available,
         *         or {@code "unavailable"} otherwise.
         */
        @Override
        public Set<String> getAuthorities() {
            return (directory != null) ? super.getAuthorities() : Collections.emptySet();
        }

        /**
         * Returns {@code null} since the user is presumed to have downloaded the files himself.
         *
         * @return the terms of use in plain text or HTML, or {@code null} if the license is presumed already accepted.
         */
        @Override
        public String getLicense(String authority, Locale locale, String mimeType) {
            return null;
        }

        /**
         * Opens the input stream for the SQL script of the given name.
         *
         * @param  name  name of the script file to open.
         * @return an input stream opened of the given script file, or {@code null} if the resource was not found.
         * @throws IOException if an error occurred while opening the file.
         */
        @Override
        protected InputStream openStream(final String name) throws IOException {
            return (directory != null) ? Files.newInputStream(directory.resolve(name)) : null;
        }
    }
}
