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

import java.util.Date;
import java.util.Map;
import java.util.HashMap;
import java.time.Instant;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.TemporalCRS;
import org.opengis.referencing.crs.VerticalCRS;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.GeocentricCRS;
import org.opengis.referencing.crs.ProjectedCRS;
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.cs.EllipsoidalCS;
import org.opengis.referencing.datum.TemporalDatum;
import org.opengis.referencing.datum.VerticalDatum;
import org.opengis.referencing.datum.VerticalDatumType;
import org.apache.sis.internal.metadata.AxisNames;
import org.apache.sis.internal.referencing.VerticalDatumTypes;
import org.apache.sis.internal.util.Constants;

// Test dependencies
import org.opengis.test.Validators;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
import org.junit.Test;

import static org.apache.sis.test.MetadataAssert.*;
import static org.apache.sis.test.TestUtilities.*;


/**
 * Tests the {@link CommonCRS} class.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 1.1
 * @since   0.4
 * @module
 */
@DependsOn({
  org.apache.sis.referencing.crs.DefaultGeodeticCRSTest.class,
  org.apache.sis.referencing.datum.DefaultVerticalDatumTest.class,
  StandardDefinitionsTest.class
})
public final strictfp class CommonCRSTest extends TestCase {
    /**
     * Length of a day in milliseconds.
     */
    private static final double DAY_LENGTH = 24 * 60 * 60 * 1000;

    /**
     * Verifies that the same EPSG code is not used for two objects. Collisions are not allowed between
     * {@code geographic}, {@code geocentric}, {@code geo3D} and all UTM projections. Strictly speaking
     * all the above-cited codes may collide with {@code datum} and {@code ellipsoid}, but we nevertheless
     * avoid those collisions in order to simplify {@link EPSGFactoryFallback#createObject(String)} implementation.
     */
    @Test
    public void ensureNoCodeCollision() {
        final Map<Integer,Enum<?>> codes = new HashMap<>();
        final CommonCRS[] values = CommonCRS.values();
        for (final CommonCRS crs : values) {
            assertNoCodeCollision(codes, crs, crs.geographic);
            assertNoCodeCollision(codes, crs, crs.geocentric);
            assertNoCodeCollision(codes, crs, crs.geo3D);
            assertNoCodeCollision(codes, crs, crs.northUPS);
            assertNoCodeCollision(codes, crs, crs.southUPS);
            for (int zone = crs.firstZone; zone <= crs.lastZone; zone++) {
                if (crs.northUTM != 0) assertNoCodeCollision(codes, crs, crs.northUTM + zone);
                if (crs.southUTM != 0) assertNoCodeCollision(codes, crs, crs.southUTM + zone);
            }
        }
        final CommonCRS.Vertical[] vertical = CommonCRS.Vertical.values();
        for (final CommonCRS.Vertical crs : vertical) {
            if (crs.isEPSG) {
                assertNoCodeCollision(codes, crs, crs.crs);
            }
        }
        /*
         * Following restrictions are not strictly required, but their enforcement
         * simplifies the EPSGFactoryFallback.createObject(String) implementation.
         */
        assertNull(codes.put(Integer.valueOf(StandardDefinitions.GREENWICH), CommonCRS.WGS84));
        for (final CommonCRS crs : values) assertNull   (crs.name(),      codes.get(Integer.valueOf(crs.ellipsoid)));
        for (final CommonCRS crs : values) assertNotSame(crs.name(), crs, codes.put(Integer.valueOf(crs.ellipsoid), crs));
        for (final CommonCRS crs : values) assertNull   (crs.name(),      codes.get(Integer.valueOf(crs.datum)));
        for (final CommonCRS.Vertical crs : vertical) {
            if (crs.isEPSG) {
                assertNull(crs.name(), codes.get(Integer.valueOf(crs.datum)));
            }
        }
    }

    /**
     * Helper method for {@link #ensureNoCodeCollision()} only.
     */
    private static void assertNoCodeCollision(final Map<Integer,Enum<?>> codes, final Enum<?> crs, final int n) {
        if (n != 0) {
            final Enum<?> existing = codes.put(n, crs);
            if (existing != null) {
                fail(existing + " and " + crs + " both use the same EPSG:" + n + " code.");
            }
        }
    }

    /**
     * Tests the {@link CommonCRS#geographic()} method.
     */
    @Test
    public void testGeographic() {
        final GeographicCRS geographic = CommonCRS.WGS84.geographic();
        Validators.validate(geographic);
        GeodeticObjectVerifier.assertIsWGS84(geographic, true, true);
        assertSame("Cached value", geographic, CommonCRS.WGS84.geographic());
    }

    /**
     * Tests the {@link CommonCRS#normalizedGeographic()} method.
     */
    @Test
    @DependsOnMethod("testGeographic")
    public void testNormalizedGeographic() {
        final GeographicCRS geographic = CommonCRS.WGS84.geographic();
        final GeographicCRS normalized = CommonCRS.WGS84.normalizedGeographic();
        Validators.validate(normalized);
        assertSame(geographic.getDatum(), normalized.getDatum());
        /*
         * Compare axes. Note that axes in different order have different EPSG codes.
         */
        final CoordinateSystem φλ = geographic.getCoordinateSystem();
        final CoordinateSystem λφ = normalized.getCoordinateSystem();
        assertEqualsIgnoreMetadata(φλ.getAxis(1), λφ.getAxis(0));       // Longitude
        assertEqualsIgnoreMetadata(φλ.getAxis(0), λφ.getAxis(1));       // Latitude
        assertSame("Cached value", normalized, CommonCRS.WGS84.normalizedGeographic());
    }

    /**
     * Tests the {@link CommonCRS#geographic3D()} method.
     */
    @Test
    @DependsOnMethod("testGeographic")
    public void testGeographic3D() {
        final GeographicCRS crs = CommonCRS.WGS72.geographic3D();
        Validators.validate(crs);
        assertEquals ("WGS 72", crs.getName().getCode());
        assertSame   (CommonCRS.WGS72.geographic().getDatum(), crs.getDatum());
        assertNotSame(CommonCRS.WGS84.geographic().getDatum(), crs.getDatum());

        final EllipsoidalCS cs = crs.getCoordinateSystem();
        final String name = cs.getName().getCode();
        assertTrue(name, name.startsWith("Ellipsoidal 3D"));
        assertEquals("dimension", 3, cs.getDimension());
        assertAxisDirectionsEqual(name, cs, AxisDirection.NORTH, AxisDirection.EAST, AxisDirection.UP);
        assertSame("Cached value", crs, CommonCRS.WGS72.geographic3D());
    }

    /**
     * Tests the {@link CommonCRS#geocentric()} method.
     */
    @Test
    @DependsOnMethod("testGeographic3D")
    public void testGeocentric() {
        final GeocentricCRS crs = CommonCRS.WGS72.geocentric();
        Validators.validate(crs);
        assertEquals ("WGS 72", crs.getName().getCode());
        assertSame   (CommonCRS.WGS72.geographic().getDatum(), crs.getDatum());
        assertNotSame(CommonCRS.WGS84.geographic().getDatum(), crs.getDatum());

        final CoordinateSystem cs = crs.getCoordinateSystem();
        final String name = cs.getName().getCode();
        assertTrue(name, name.startsWith("Earth centred"));
        assertEquals("dimension", 3, cs.getDimension());
        assertAxisDirectionsEqual(name, cs, AxisDirection.GEOCENTRIC_X,
                AxisDirection.GEOCENTRIC_Y, AxisDirection.GEOCENTRIC_Z);
        assertSame("Cached value", crs, CommonCRS.WGS72.geocentric());
    }

    /**
     * Tests the {@link CommonCRS#spherical()} method.
     */
    @Test
    @DependsOnMethod("testGeographic3D")
    public void testSpherical() {
        final GeocentricCRS crs = CommonCRS.ETRS89.spherical();
        Validators.validate(crs);
        assertEquals ("ETRS89", crs.getName().getCode());
        assertSame   (CommonCRS.ETRS89.geographic().getDatum(), crs.getDatum());
        assertNotSame(CommonCRS.WGS84 .geographic().getDatum(), crs.getDatum());

        final CoordinateSystem cs = crs.getCoordinateSystem();
        final String name = cs.getName().getCode();
        assertTrue(name, name.startsWith("Spherical"));
        assertEquals("dimension", 3, cs.getDimension());
        assertAxisDirectionsEqual(name, cs, AxisDirection.NORTH, AxisDirection.EAST, AxisDirection.UP);
        assertSame("Cached value", crs, CommonCRS.ETRS89.spherical());
    }

    /**
     * Verifies the vertical datum enumeration.
     */
    @Test
    public void testVertical() {
        for (final CommonCRS.Vertical e : CommonCRS.Vertical.values()) {
            final VerticalDatumType datumType;
            final String axisName, datumName;
            switch (e) {
                case NAVD88:         axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "North American Vertical Datum 1988"; datumType = VerticalDatumType. GEOIDAL;       break;
                case BAROMETRIC:     axisName = "Barometric altitude";            datumName = "Constant pressure surface";          datumType = VerticalDatumType. BAROMETRIC;    break;
                case MEAN_SEA_LEVEL: axisName = AxisNames.GRAVITY_RELATED_HEIGHT; datumName = "Mean Sea Level";                     datumType = VerticalDatumType. GEOIDAL;       break;
                case DEPTH:          axisName = AxisNames.DEPTH;                  datumName = "Mean Sea Level";                     datumType = VerticalDatumType. GEOIDAL;       break;
                case ELLIPSOIDAL:    axisName = AxisNames.ELLIPSOIDAL_HEIGHT;     datumName = "Ellipsoid";                          datumType = VerticalDatumTypes.ELLIPSOIDAL;   break;
                case OTHER_SURFACE:  axisName = "Height";                         datumName = "Other surface";                      datumType = VerticalDatumType. OTHER_SURFACE; break;
                default: throw new AssertionError(e);
            }
            final String        name  = e.name();
            final VerticalDatum datum = e.datum();
            final VerticalCRS   crs   = e.crs();
            if (e.isEPSG) {
                /*
                 * BAROMETRIC, ELLIPSOIDAL and OTHER_SURFACE uses an axis named "Height", which is not
                 * a valid axis name according ISO 19111. We skip the validation test for those enums.
                 */
                Validators.validate(crs);
            }
            assertSame  (name, datum,          e.datum());                      // Datum before CRS creation.
            assertSame  (name, crs.getDatum(), e.datum());                      // Datum after CRS creation.
            assertEquals(name, datumName, datum.getName().getCode());
            assertEquals(name, datumType, datum.getVerticalDatumType());
            assertEquals(name, axisName,  crs.getCoordinateSystem().getAxis(0).getName().getCode());
        }
    }

    /**
     * Verifies the epoch values of temporal enumeration compared to the Julian epoch.
     *
     * @see <a href="http://en.wikipedia.org/wiki/Julian_day">Wikipedia: Julian day</a>
     */
    @Test
    public void testTemporal() {
        final double julianEpoch = CommonCRS.Temporal.JULIAN.datum().getOrigin().getTime() / DAY_LENGTH;
        assertTrue(julianEpoch < 0);
        for (final CommonCRS.Temporal e : CommonCRS.Temporal.values()) {
            final String epoch;
            final double days;
            switch (e) {
                case JAVA:             // Fall through
                case UNIX:             epoch = "1970-01-01 00:00:00"; days = 2440587.5; break;
                case TRUNCATED_JULIAN: epoch = "1968-05-24 00:00:00"; days = 2440000.5; break;
                case DUBLIN_JULIAN:    epoch = "1899-12-31 12:00:00"; days = 2415020.0; break;
                case MODIFIED_JULIAN:  epoch = "1858-11-17 00:00:00"; days = 2400000.5; break;
                case JULIAN:           epoch = "4713-01-01 12:00:00"; days = 0;         break;
                default: throw new AssertionError(e);
            }
            final String        name   = e.name();
            final TemporalDatum datum  = e.datum();
            final TemporalCRS   crs    = e.crs();
            final Date          origin = datum.getOrigin();
            Validators.validate(crs);
            assertSame  (name, datum,          e.datum());              // Datum before CRS creation.
            assertSame  (name, crs.getDatum(), e.datum());              // Datum after CRS creation.
            assertEquals(name, epoch, format(origin));
            assertEquals(name, days, origin.getTime() / DAY_LENGTH - julianEpoch, 0);
        }
    }

    /**
     * Tests {@link CommonCRS#universal(double, double)} with Universal Transverse Mercator (UTM) projections.
     *
     * @since 0.7
     */
    @Test
    @DependsOnMethod("testGeographic")
    public void testUTM() {
        final ProjectedCRS crs = CommonCRS.WGS72.universal(-45, -122);
        assertEquals("name", "WGS 72 / UTM zone 10S", crs.getName().getCode());
        final ParameterValueGroup pg = crs.getConversionFromBase().getParameterValues();
        assertEquals(Constants.LATITUDE_OF_ORIGIN,    0, pg.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(), STRICT);
        assertEquals(Constants.CENTRAL_MERIDIAN,   -123, pg.parameter(Constants.CENTRAL_MERIDIAN)  .doubleValue(), STRICT);
        assertEquals(Constants.SCALE_FACTOR,     0.9996, pg.parameter(Constants.SCALE_FACTOR)      .doubleValue(), STRICT);
        assertEquals(Constants.FALSE_EASTING,    500000, pg.parameter(Constants.FALSE_EASTING)     .doubleValue(), STRICT);
        assertEquals(Constants.FALSE_NORTHING, 10000000, pg.parameter(Constants.FALSE_NORTHING)    .doubleValue(), STRICT);
        assertSame("Expected a cached instance.", crs, CommonCRS.WGS72.universal(-45, -122));
        assertNotSame("Expected a new instance.", crs, CommonCRS.WGS72.universal(+45, -122));
    }

    /**
     * Tests {@link CommonCRS#universal(double, double)} with Universal Polar Stereographic (UPS) projections.
     *
     * @since 0.8
     */
    @Test
    @DependsOnMethod("testGeographic")
    public void testUPS() {
        final ProjectedCRS crs = CommonCRS.WGS72.universal(-85, -122);
        assertEquals("name", "WGS 72 / Universal Polar Stereographic South", crs.getName().getCode());
        final ParameterValueGroup pg = crs.getConversionFromBase().getParameterValues();
        assertEquals(Constants.LATITUDE_OF_ORIGIN, -90, pg.parameter(Constants.LATITUDE_OF_ORIGIN).doubleValue(), STRICT);
        assertEquals(Constants.CENTRAL_MERIDIAN,     0, pg.parameter(Constants.CENTRAL_MERIDIAN)  .doubleValue(), STRICT);
        assertEquals(Constants.SCALE_FACTOR,     0.994, pg.parameter(Constants.SCALE_FACTOR)      .doubleValue(), STRICT);
        assertEquals(Constants.FALSE_EASTING,  2000000, pg.parameter(Constants.FALSE_EASTING)     .doubleValue(), STRICT);
        assertEquals(Constants.FALSE_NORTHING, 2000000, pg.parameter(Constants.FALSE_NORTHING)    .doubleValue(), STRICT);
        assertSame("Expected a cached instance.", crs, CommonCRS.WGS72.universal(-85, -122));
        assertNotSame("Expected a new instance.", crs, CommonCRS.WGS72.universal(+85, -122));
    }

    /**
     * Tests {@link CommonCRS#forDatum(CoordinateReferenceSystem)}.
     *
     * @sinc 0.8
     */
    @Test
    @DependsOnMethod("testGeographic")
    public void testForDatum() {
        assertSame("WGS84", CommonCRS.WGS84, CommonCRS.forDatum(CommonCRS.WGS84.geographic()));
        assertSame("WGS72", CommonCRS.WGS72, CommonCRS.forDatum(CommonCRS.WGS72.geographic()));
    }

    /**
     * Tests {@link CommonCRS.Temporal#forEpoch(Instant)}.
     */
    @Test
    public void testForEpoch() {
        assertSame(CommonCRS.Temporal.UNIX, CommonCRS.Temporal.forEpoch(Instant.ofEpochMilli(0)));        // As specified in Javadoc.
    }

    /**
     * Tests formatting in a {@link java.util.Formatter}.
     *
     * @since 1.1
     */
    @Test
    public void testFormat() {
        assertEquals("World Geodetic System 1984", String.format("%s", CommonCRS.WGS84.datum()));
        assertEquals("WORLD GEODETIC SYSTEM 1984", String.format("%S", CommonCRS.WGS84.datum()));
        assertTrue(String.format("%#s", CommonCRS.WGS84.datum()).endsWith(":6326"));
    }
}
