/*
 * 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.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.
     */
    @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, false);
        }
    }

    /**
     * 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();
        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;
        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();
        isInverseTransformSupported = false;
        verifyInDomain(CoordinateDomain.GEOGRAPHIC, 3534897149662911157L);
    }
}
