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

import java.util.Date;
import java.util.Map;
import java.util.EnumMap;
import java.util.Iterator;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.internal.storage.AbstractResource;
import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
import org.apache.sis.setup.GeometryLibrary;
import org.opengis.test.dataset.TestData;
import ucar.nc2.dataset.NetcdfDataset;
import ucar.nc2.NetcdfFile;
import org.junit.AfterClass;

import static org.junit.Assert.*;


/**
 * Base class of netCDF tests. The base class uses the UCAR decoder, which is taken as a reference implementation.
 * Subclasses testing Apache SIS implementation needs to override the {@link #createDecoder(TestData)}.
 *
 * <p>This class is <strong>not</strong> thread safe - do not run subclasses in parallel.</p>
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.3
 * @module
 */
public abstract strictfp class TestCase extends org.apache.sis.test.TestCase {
    /**
     * The {@code searchPath} argument value to be given to the {@link Decoder#setSearchPath(String[])}
     * method when the decoder shall search only in global attributes.
     */
    private static final String[] GLOBAL = new String[1];

    /**
     * The decoders cached by {@link #selectDataset(TestData)}.
     * The map is non-empty only during the execution of a single test class.
     *
     * @see #closeAllDecoders()
     */
    private static final Map<TestData,Decoder> DECODERS = new EnumMap<>(TestData.class);

    /**
     * The decoder to test, which is set by {@link #selectDataset(TestData)}.
     * This field must be set before any {@code assert} method is invoked.
     */
    private Decoder decoder;

    /**
     * Creates a new test case.
     */
    protected TestCase() {
    }

    /**
     * Creates a netCDF reader from the UCAR library for the specified data set.
     * We use the UCAR library as a reference implementation for the tests.
     *
     * @param  file  the dataset as one of the {@code NETCDF_*} constants.
     * @return the decoder for the specified dataset.
     * @throws IOException if an I/O error occurred while opening the file.
     */
    protected static NetcdfFile createUCAR(final TestData file) throws IOException {
        /*
         * Binary netCDF files need to be read either from a file, or from a byte array in memory.
         * Reading from a file is not possible if the test file is in geoapi-conformance JAR file.
         * But since those test files are less than 15 kilobytes, loading them in memory is okay.
         */
        String location = file.location().toString();
        location = location.substring(location.lastIndexOf('/') + 1);
        return NetcdfFile.openInMemory(location, file.content());
    }

    /**
     * Invoked when a new {@link Decoder} instance needs to be created for the specified dataset.
     * The {@code file} parameter can be one of the following values:
     *
     * <ul>
     *   <li>{@link TestData#NETCDF_2D_GEOGRAPHIC} — uses a geographic CRS for global data over the world.</li>
     *   <li>{@link TestData#NETCDF_4D_PROJECTED}  — uses a projected CRS with elevation and time.</li>
     * </ul>
     *
     * Default implementation opens the file with UCAR netCDF library and wraps the UCAR object in {@link DecoderWrapper}.
     * We proceeded that way because we use UCAR library as the reference implementation.
     * Subclasses override this method for testing with Apache SIS implementation.
     *
     * @param  file  the dataset as one of the above-cited constants.
     * @return the decoder for the specified dataset.
     * @throws IOException if an I/O error occurred while opening the file.
     * @throws DataStoreException if a logical error occurred.
     */
    protected Decoder createDecoder(final TestData file) throws IOException, DataStoreException {
        return new DecoderWrapper(new NetcdfDataset(createUCAR(file)), GeometryLibrary.JAVA2D, new AbstractResource(null));
    }

    /**
     * Selects the dataset to use for the tests. If a decoder for the given name has already been
     * opened, then this method returns that decoder. Otherwise a new decoder is created by a call
     * to {@link #createDecoder(TestData)}, then cached.
     *
     * <p>The {@linkplain Decoder#setSearchPath(String[]) search path} of the returned decoder
     * is initialized to the global attributes only.</p>
     *
     * @param  name  the file as one of the constants enumerated in the {@link #createDecoder(TestData)} method.
     * @return the decoder for the given name.
     * @throws IOException if an I/O error occurred while opening the file.
     * @throws DataStoreException if a logical error occurred.
     */
    protected final Decoder selectDataset(final TestData name) throws IOException, DataStoreException {
        synchronized (DECODERS) {               // Paranoiac safety, but should not be used in multi-threads environment.
            decoder = DECODERS.get(name);
            if (decoder == null) {
                decoder = createDecoder(name);
                assertNotNull(decoder);
                assertNull(DECODERS.put(name, decoder));
            }
            decoder.setSearchPath(GLOBAL);
            return decoder;                     // Reminder: Decoder instances are not thread-safe.
        }
    }

    /**
     * Returns the decoder being tested.
     */
    final Decoder decoder() {
        return decoder;
    }

    /**
     * Invoked after all tests in a class have been executed.
     * This method closes all netCDF files.
     *
     * @throws IOException if an error occurred while closing a file.
     */
    @AfterClass
    public static void closeAllDecoders() throws IOException {
        Throwable failure = null;
        synchronized (DECODERS) {               // Paranoiac safety.
            final Iterator<Decoder> it = DECODERS.values().iterator();
            while (it.hasNext()) {
                final Decoder decoder = it.next();
                try {
                    decoder.close();
                } catch (Throwable e) {
                    if (failure == null) {
                        failure = e;
                    } else {
                        failure.addSuppressed(e);
                    }
                }
                it.remove();
            }
            assertTrue(DECODERS.isEmpty());
        }
        /*
         * If we failed to close a file, propagates the error
         * only after we have closed all other files.
         */
        if (failure != null) {
            if (failure instanceof IOException) {
                throw (IOException) failure;
            }
            if (failure instanceof RuntimeException) {
                throw (RuntimeException) failure;
            }
            if (failure instanceof Error) {
                throw (Error) failure;
            }
            throw new UndeclaredThrowableException(failure);
        }
    }

    /**
     * Asserts that the textual value of the named attribute is equals to the expected value.
     * The {@link #selectDataset(TestData)} method must be invoked at least once before this method.
     *
     * @param  expected       the expected attribute value.
     * @param  attributeName  the name of the attribute to test.
     * @throws IOException if an error occurred while reading the netCDF file.
     */
    protected final void assertAttributeEquals(final String expected, final String attributeName) throws IOException {
        assertEquals(attributeName, expected, decoder.stringValue(attributeName));
    }

    /**
     * Asserts that the numeric value of the named attribute is equals to the expected value.
     * The {@link #selectDataset(TestData)} method must be invoked at least once before this method.
     *
     * @param  expected       the expected attribute value.
     * @param  attributeName  the name of the attribute to test.
     * @throws IOException if an error occurred while reading the netCDF file.
     */
    protected final void assertAttributeEquals(final Number expected, final String attributeName) throws IOException {
        assertEquals(attributeName, expected, decoder.numericValue(attributeName));
    }

    /**
     * Asserts that the temporal value of the named attribute is equals to the expected value.
     * The {@link #selectDataset(TestData)} method must be invoked at least once before this method.
     *
     * @param  expected       the expected attribute value.
     * @param  attributeName  the name of the attribute to test.
     * @throws IOException if an error occurred while reading the netCDF file.
     */
    protected final void assertAttributeEquals(final Date expected, final String attributeName) throws IOException {
        assertEquals(attributeName, expected, decoder.dateValue(attributeName));
    }
}
