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

import org.opengis.test.CalculationType;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.referencing.datum.HardCodedDatum;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.junit.Test;

import static org.apache.sis.test.Assert.*;
import static java.lang.StrictMath.toRadians;


/**
 * Tests {@link AbridgedMolodenskyTransform2D}. This class takes {@link MolodenskyTransform}
 * as a reference implementation and verifies that we get consistent results. We rely on the
 * fact that {@link MolodenskyTransform#transform(double[], int, double[], int, boolean)} is
 * not overridden.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 * @since   0.8
 * @module
 */
@DependsOn(MolodenskyTransformTest.class)
public final strictfp class AbridgedMolodenskyTransformTest extends MathTransformTestCase {
    /**
     * Creates a new test case.
     */
    public AbridgedMolodenskyTransformTest() {
        final double delta = toRadians(100.0 / 60) / 1852;      // Approximately 100 metres
        derivativeDeltas   = new double[] {delta, delta};       // (Δλ, Δφ)
        λDimension         = new int[] {0};                     // Dimension for which to ignore ±360° differences.
        tolerance          = Formulas.ANGULAR_TOLERANCE;        // Tolerance for longitude and latitude in degrees
    }

    /**
     * Compares the abridged Molodensky transform with a non-abridged one.
     * This test works on angular values in radians, without concatenated transforms.
     *
     * @throws FactoryException if an error occurred while creating a transform step.
     * @throws TransformException if a transformation failed.
     *
     * @see MolodenskyTransformTest#compareWithGeocentricTranslation()
     */
    @Test
    public void compareWithReferenceImplementation() throws FactoryException, TransformException {
        final AbstractMathTransform transform = new AbridgedMolodenskyTransform2D(
                HardCodedDatum.WGS84 .getEllipsoid(),
                HardCodedDatum.SPHERE.getEllipsoid());
        this.transform = transform;
        tolerance = toRadians(tolerance);
        final double[] sources  = generateRandomCoordinates(CoordinateDomain.GEOGRAPHIC_RADIANS, 0f);
        final double[] targets  = new double[2];
        final double[] expected = new double[2];
        for (int i=0; i<sources.length; i+=2) {
            transform.transform(sources, i, targets,  0, 1);        // Use the overridden method.
            transform.transform(sources, i, expected, 0, false);    // Use the MolodenskyTransform method.
            assertCoordinateEquals("transform", expected, targets, 0, CalculationType.DIRECT_TRANSFORM);
        }
    }

    /**
     * Creates an abridged Molodensky transform working on geographic coordinates in degrees.
     * It should be an {@link AbridgedMolodenskyTransform2D} instance concatenated with affine transforms.
     */
    private static MathTransform create() throws FactoryException {
        final MathTransform tr = MolodenskyTransform.createGeodeticTransformation(
                        DefaultFactories.forBuildin(MathTransformFactory.class),
                        HardCodedDatum.WGS84 .getEllipsoid(), false,
                        HardCodedDatum.SPHERE.getEllipsoid(), false, 0, 0, 0, true);
        int n = 0;
        for (final MathTransform step : MathTransforms.getSteps(tr)) {
            if (!(step instanceof LinearTransform)) {
                assertInstanceOf("kernel", AbridgedMolodenskyTransform2D.class, step);
                n++;
            }
        }
        assertEquals("Number of Molodensky transform instance", 1, n);
        return tr;
    }

    /**
     * Verifies consistency of all transform methods. This method tests the full operation chain,
     * including the conversions from degrees to radians.
     *
     * @throws FactoryException if an error occurred while creating a transform step.
     * @throws TransformException if a transformation failed.
     */
    @Test
    @DependsOnMethod("compareWithReferenceImplementation")
    public void testConsistency() throws FactoryException, TransformException {
        transform = create();
        validate();
        isDerivativeSupported = false;
        isInverseTransformSupported = false;
        verifyInDomain(CoordinateDomain.GEOGRAPHIC, -1941624852762631518L);
        /*
         * Calculation of "expected" transform derivative by finite difference
         * does not seem accurate enough for the default accuracy. (Actually,
         * we are not completely sure that there is no bug in derivative formula).
         */
        tolerance *= 10;
        isDerivativeSupported = true;
        verifyInDomain(CoordinateDomain.GEOGRAPHIC, 4350796528249596132L);
    }

    /**
     * Tests a deserialized instance. The intent is to verify that the transient fields
     * are correctly recomputed.
     *
     * @throws FactoryException if an error occurred while creating a transform step.
     * @throws TransformException if a transformation failed.
     */
    @Test
    @DependsOnMethod("testConsistency")
    public void testSerialization() throws FactoryException, TransformException {
        transform = assertSerializedEquals(create());
        validate();
        isDerivativeSupported = false;
        isInverseTransformSupported = false;
        verifyInDomain(CoordinateDomain.GEOGRAPHIC, 3534897149662911157L);
    }
}
