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

import java.util.Map;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlRootElement;
import javax.measure.IncommensurableException;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.Datum;
import org.apache.sis.referencing.cs.CoordinateSystems;
import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.privy.ReferencingUtilities;
import org.apache.sis.referencing.internal.Resources;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.resources.Errors;

// Specific to the main and geoapi-3.1 branches:
import org.opengis.referencing.operation.Projection;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.ProjectedCRS;


/**
 * A parameterized mathematical operation that converts coordinates to another CRS without any change of
 * {@linkplain org.apache.sis.referencing.datum.AbstractDatum datum}.
 * The best-known example of a coordinate conversion is a map projection.
 * The parameters describing coordinate conversions are defined rather than empirically derived.
 *
 * <p>This coordinate operation contains an {@linkplain DefaultOperationMethod operation method}, usually
 * with associated {@linkplain org.apache.sis.parameter.DefaultParameterValueGroup parameter values}.
 * In the SIS implementation, the parameter values can be either inferred from the
 * {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform math transform}
 * or explicitly provided at construction time in a <dfn>defining conversion</dfn> (see below).</p>
 *
 * <h2>Defining conversions</h2>
 * {@code OperationMethod} instances are generally created for a pair of existing {@linkplain #getSourceCRS() source}
 * and {@linkplain #getTargetCRS() target CRS}. But {@code Conversion} instances without those information may exist
 * temporarily while creating a {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS derived} or
 * {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS projected CRS}.
 * Those <i>defining conversions</i> have no source and target CRS since those elements are provided by the
 * derived or projected CRS themselves. This class provides a {@linkplain #DefaultConversion(Map, OperationMethod,
 * MathTransform, ParameterValueGroup) constructor} for such defining conversions.
 *
 * <p>After the source and target CRS become known, we can invoke the {@link #specialize specialize(…)} method for
 * {@linkplain DefaultMathTransformFactory#createParameterizedTransform creating a math transform from the parameters}
 * and assign the source and target CRS to it.</p>
 *
 * <h2>Immutability and thread safety</h2>
 * This class is immutable and thus thread-safe if the property <em>values</em> (not necessarily the map itself)
 * given to the constructor are also immutable. This means that unless otherwise noted in the javadoc,
 * {@code Conversion} instances created using only SIS factories and static constants can be shared
 * by many objects and passed between threads without synchronization.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 1.5
 *
 * @see DefaultTransformation
 *
 * @since 0.6
 */
@XmlType(name = "ConversionType")
@XmlRootElement(name = "Conversion")
public class DefaultConversion extends AbstractSingleOperation implements Conversion {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -2148164324805562793L;

    /**
     * Creates a coordinate conversion from the given properties.
     * The properties given in argument follow the same rules as for the
     * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem,
     * CoordinateReferenceSystem, CoordinateReferenceSystem, MathTransform) super-class constructor}.
     * The following table is a reminder of main (not all) properties:
     *
     * <table class="sis">
     *   <caption>Recognized properties (non exhaustive list)</caption>
     *   <tr>
     *     <th>Property name</th>
     *     <th>Value type</th>
     *     <th>Returned by</th>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
     *     <td>{@link #getName()}</td>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
     *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
     *     <td>{@link #getIdentifiers()}</td>
     *   </tr><tr>
     *     <td>{@value org.opengis.referencing.ObjectDomain#DOMAIN_OF_VALIDITY_KEY}</td>
     *     <td>{@link org.opengis.metadata.extent.Extent}</td>
     *     <td>{@link org.apache.sis.referencing.DefaultObjectDomain#getDomainOfValidity()}</td>
     *   </tr>
     * </table>
     *
     * <h4>Relationship between datum</h4>
     * By definition, coordinate <b>conversions</b> do not change the datum. Consequently, the given {@code sourceCRS}
     * and {@code targetCRS} should use the same datum. If the datum is not the same, then the coordinate operation
     * should probably be a {@linkplain DefaultTransformation transformation} instead.
     * However, Apache SIS does not enforce that condition, but we encourage users to follow it.
     * The reason why SIS is tolerant is because some gray areas may exist about whether an operation
     * should be considered as a conversion or a transformation.
     *
     * <p>Note that while Apache SIS accepts to construct {@code DefaultConversion} instances
     * with different source and target datum, it does not accept to use such instances for
     * {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS derived CRS} construction.</p>
     *
     * <h4>Example</h4>
     * Converting time instants from a {@linkplain org.apache.sis.referencing.crs.DefaultTemporalCRS temporal CRS}
     * using the <i>January 1st, 1950</i> epoch to another temporal CRS using the <i>January 1st, 1970</i> epoch is
     * a datum change, since the epoch is part of {@linkplain org.apache.sis.referencing.datum.DefaultTemporalDatum
     * temporal datum} definition. However, such operation does not have all the accuracy issues of transformations
     * between geodetic reference frames (empirically determined, over-determined systems, stochastic nature of the parameters).
     * Consequently, some users may consider sufficient to represent temporal epoch changes as conversions instead
     * than transformations.
     *
     * @param properties        the properties to be given to the identified object.
     * @param sourceCRS         the source CRS.
     * @param targetCRS         the target CRS, which shall use a datum {@linkplain Utilities#equalsIgnoreMetadata
     *                          equals (ignoring metadata)} to the source CRS datum.
     * @param interpolationCRS  the CRS of additional coordinates needed for the operation, or {@code null} if none.
     * @param method            the coordinate operation method (mandatory in all cases).
     * @param transform         transform from positions in the source CRS to positions in the target CRS.
     */
    public DefaultConversion(final Map<String,?>             properties,
                             final CoordinateReferenceSystem sourceCRS,
                             final CoordinateReferenceSystem targetCRS,
                             final CoordinateReferenceSystem interpolationCRS,
                             final OperationMethod           method,
                             final MathTransform             transform)
    {
        super(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
        ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
        ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
    }

    /**
     * Creates a defining conversion from the given transform and/or parameters.
     * This conversion has no source and target CRS since those elements are usually unknown
     * at <i>defining conversion</i> construction time.
     * The source and target CRS will become known later, at the
     * {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS Derived CRS} or
     * {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected CRS}
     * construction time.
     *
     * <p>The {@code properties} map given in argument follows the same rules as for the
     * {@linkplain #DefaultConversion(Map, CoordinateReferenceSystem, CoordinateReferenceSystem,
     * CoordinateReferenceSystem, OperationMethod, MathTransform) above constructor}.</p>
     *
     * <h4>Transform and parameters arguments</h4>
     * At least one of the {@code transform} or {@code parameters} argument must be non-null.
     * If the caller supplies a {@code transform} argument, then it shall be a transform expecting
     * {@linkplain org.apache.sis.referencing.cs.AxesConvention#NORMALIZED normalized} input coordinates
     * and producing normalized output coordinates. See {@link org.apache.sis.referencing.cs.AxesConvention}
     * for more information about what Apache SIS means by "normalized".
     *
     * <p>If the caller cannot yet supply a {@code MathTransform}, then (s)he shall supply the parameter values needed
     * for creating that transform, with the possible omission of {@code "semi_major"} and {@code "semi_minor"} values.
     * The semi-major and semi-minor parameter values will be set automatically when the
     * {@link #specialize specialize(…)} method will be invoked.</p>
     *
     * <p>If both the {@code transform} and {@code parameters} arguments are non-null, then the latter should describe
     * the parameters used for creating the transform. Those parameters will be stored for information purpose and can
     * be given back by the {@link #getParameterValues()} method.</p>
     *
     * @param properties  the properties to be given to the identified object.
     * @param method      the operation method.
     * @param transform   transform from positions in the source CRS to positions in the target CRS, or {@code null}.
     * @param parameters  the {@code transform} parameter values, or {@code null}.
     *
     * @see DefaultMathTransformFactory#swapAndScaleAxes(MathTransform, DefaultMathTransformFactory.Context)
     */
    @SuppressWarnings("this-escape")    // False positive.
    public DefaultConversion(final Map<String,?>       properties,
                             final OperationMethod     method,
                             final MathTransform       transform,
                             final ParameterValueGroup parameters)
    {
        super(properties, method);
        this.transform = transform;
        if (transform == null && parameters == null) {
            throw new IllegalArgumentException(Resources.forProperties(properties)
                    .getString(Resources.Keys.UnspecifiedParameterValues));
        }
        setParameterValues(parameters, null);
        checkDimensions(properties);
    }

    /**
     * Constructs a new conversion with the same values as the specified one, together with the
     * specified source and target CRS. While the source conversion can be an arbitrary one,
     * it is typically a defining conversion.
     *
     * @param definition  the defining conversion.
     * @param source      the new source CRS.
     * @param target      the new target CRS.
     * @param factory     the factory to use for creating a transform from the parameters or for performing axis changes.
     */
    @SuppressWarnings("deprecation")
    DefaultConversion(final Conversion definition,
                      final CoordinateReferenceSystem source,
                      final CoordinateReferenceSystem target,
                      final MathTransformFactory factory) throws FactoryException
    {
        super(definition);
        int interpDim = ReferencingUtilities.getDimension(super.getInterpolationCRS().orElse(null));
        if (transform == null) {
            /*
             * If the user did not specified explicitly a MathTransform, we will need to create it from the parameters.
             * This case happen when creating a ProjectedCRS because the length of semi-major and semi-minor axes are
             * often missing at defining conversion creation time. Since this constructor know those semi-axis lengths
             * thanks to the `sourceCRS` argument, we can complete the parameters.
             */
            if (parameters == null) {
                throw new IllegalArgumentException(Resources.format(Resources.Keys.UnspecifiedParameterValues));
            }
            if (factory instanceof DefaultMathTransformFactory) {
                /*
                 * Apache SIS specific API (not yet defined in GeoAPI, but could be proposed).
                 * Note that setTarget(…) intentionally uses only the CoordinateSystem instead of the full
                 * CoordinateReferenceSystem because the targetCRS is typically under construction when this
                 * method in invoked, and attempts to use it can cause NullPointerException.
                 */
                final DefaultMathTransformFactory.Context context;
                if (target instanceof GeneralDerivedCRS) {
                    context = ReferencingUtilities.createTransformContext(source, null);
                    context.setTarget(target.getCoordinateSystem());    // Using `target` would be unsafe here.
                } else {
                    context = ReferencingUtilities.createTransformContext(source, target);
                }
                transform = ((DefaultMathTransformFactory) factory).createParameterizedTransform(parameters, context);
                setParameterValues(context.getCompletedParameters(), context.getContextualParameters());
            } else {
                /*
                 * Fallback for non-SIS implementation. Equivalent to the above code, except that we can
                 * not get the parameters completed with semi-major and semi-minor axis lengths. Most of
                 * the code should work anyway.
                 */
                transform = factory.createBaseToDerived(source, parameters, target.getCoordinateSystem());
            }
        } else {
            /*
             * If the user specified explicitly a MathTransform, we may still need to swap or scale axes.
             * If this conversion is a defining conversion (which is usually the case when creating a new
             * ProjectedCRS), then DefaultMathTransformFactory has a specialized createBaseToDerived(…)
             * method for this job.
             */
            if (sourceCRS == null && targetCRS == null && factory instanceof DefaultMathTransformFactory) {
                final var context = new DefaultMathTransformFactory.Context();
                context.setSource(source.getCoordinateSystem());
                context.setTarget(target.getCoordinateSystem());    // See comment on the other setTarget(…) call.
                transform = ((DefaultMathTransformFactory) factory).swapAndScaleAxes(transform, context);
            } else {
                /*
                 * If we cannot use our SIS factory implementation, or if this conversion is not a defining
                 * conversion (i.e. if this is the conversion of an existing ProjectedCRS, in which case the
                 * math transform may not be normalized), then we fallback on a simpler swapAndScaleAxes(…)
                 * method defined in this class. This is needed for AbstractCRS.forConvention(AxisConvention).
                 */
                transform = swapAndScaleAxes(transform, source, sourceCRS, interpDim, true,  factory);
                transform = swapAndScaleAxes(transform, targetCRS, target, interpDim, false, factory);
                interpDim = 0;  // Skip createPassThroughTransform(…) since it was handled by swapAndScaleAxes(…).
            }
        }
        if (interpDim != 0) {
            transform = factory.createPassThroughTransform(interpDim, transform, 0);
        }
        sourceCRS = source;
        targetCRS = target;
    }

    /**
     * Creates a new coordinate operation with the same values as the specified one.
     * This copy constructor provides a way to convert an arbitrary implementation into a SIS one
     * or a user-defined one (as a subclass), usually in order to leverage some implementation-specific API.
     *
     * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p>
     *
     * @param  operation  the coordinate operation to copy.
     *
     * @see #castOrCopy(Conversion)
     */
    protected DefaultConversion(final Conversion operation) {
        super(operation);
    }

    /**
     * Returns a SIS coordinate operation implementation with the values of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code DefaultConversion}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code DefaultConversion} instance is created using the
     *       {@linkplain #DefaultConversion(Conversion) copy constructor} and returned.
     *       Note that this is a <em>shallow</em> copy operation, because the other
     *       properties contained in the given object are not recursively copied.</li>
     * </ul>
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     */
    public static DefaultConversion castOrCopy(final Conversion object) {
        if (object == null || object instanceof DefaultConversion) {
            return (DefaultConversion) object;
        }
        if (object instanceof Projection) {
            return new DefaultProjection((Projection) object);
        } else {
            return new DefaultConversion(object);
        }
    }

    /**
     * Returns the GeoAPI interface implemented by this class.
     * The default implementation returns {@code Conversion.class}.
     *
     * @return the conversion interface implemented by this class.
     */
    @Override
    public Class<? extends Conversion> getInterface() {
        return Conversion.class;
    }

    /**
     * Returns a specialization of this conversion with non-null <abbr>CRS</abbr>s.
     * This {@code specialize(…)} method is typically invoked on {@linkplain #DefaultConversion(Map,
     * OperationMethod, MathTransform, ParameterValueGroup) defining conversion} instances,
     * when more information become available about the conversion to create.
     *
     * @param  sourceCRS  the source CRS.
     * @param  targetCRS  the target CRS.
     * @param  factory    the factory to use for creating a transform from the parameters
     *         or for performing axis changes, or {@code null} for the default factory.
     * @return conversion which declares the given <abbr>CRS</abbr>s as the source and target.
     * @throws MismatchedDatumException if the given CRS do not use the same datum as the source and target CRS
     *         of this conversion.
     * @throws FactoryException if the creation of a {@link MathTransform} from the {@linkplain #getParameterValues()
     *         parameter values}, or a {@linkplain CoordinateSystems#swapAndScaleAxes change of axis order or units}
     *         failed.
     *
     * @see DefaultMathTransformFactory#createParameterizedTransform(ParameterValueGroup, DefaultMathTransformFactory.Context)
     *
     * @since 1.5
     */
    @SuppressWarnings("deprecation")
    public Conversion specialize(final CoordinateReferenceSystem sourceCRS,
                                 final CoordinateReferenceSystem targetCRS,
                                 MathTransformFactory factory) throws FactoryException
    {
        ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
        ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
        /*
         * Conceptual consistency check: verify that the new CRSs use the same datum as the previous ones,
         * since the purpose of this method is not to apply datum changes. Datum changes are the purpose of
         * a dedicated kind of operations, namely Transformation.
         */
        ensureCompatibleDatum("sourceCRS", super.getSourceCRS(), sourceCRS);
        if (!(targetCRS instanceof GeneralDerivedCRS)) {
            ensureCompatibleDatum("targetCRS", super.getTargetCRS(), targetCRS);
        } else {
            /*
             * Special case for derived and projected CRS: we cannot check directly the datum of the target CRS
             * of a derived CRS, because this method is invoked indirectly by SIS AbstractDerivedCRS constructor
             * before its `conversionFromBase` field is set. Since the Apache SIS implementations of derived CRS
             * map the datum to getConversionFromBase().getSourceCRS().getDatum(), invoking targetCRS.getDatum()
             * below may result in a NullPointerException. Instead, we verify that `this` conversion use the same
             * datum for source and target CRS, since DerivedCRS and ProjectedCRS are expected to have the same
             * datum than their source CRS.
             */
            ensureCompatibleDatum("targetCRS", sourceCRS, super.getTargetCRS());
        }
        final boolean isProjection = (targetCRS instanceof ProjectedCRS) && (sourceCRS instanceof GeographicCRS);
        if (super.getSourceCRS() == sourceCRS &&
            super.getTargetCRS() == targetCRS &&
            super.getMathTransform() != null &&
            isProjection == (this instanceof Projection))
        {
            return this;
        }
        if (factory == null) {
            factory = DefaultMathTransformFactory.provider();
        }
        if (isProjection) {
            return new DefaultProjection(this, sourceCRS, targetCRS, factory);
        }
        return new DefaultConversion(this, sourceCRS, targetCRS, factory);
    }

    /**
     * Ensures that the {@code actual} CRS uses a datum which is equal, ignoring metadata,
     * to the datum of the {@code expected} CRS.
     *
     * @param  param     the parameter name, used only in case of error.
     * @param  expected  the CRS containing the expected datum, or {@code null}.
     * @param  actual    the CRS for which to check the datum, or {@code null}.
     * @throws MismatchedDatumException if the two CRS use different datum.
     */
    private static void ensureCompatibleDatum(final String param,
            final CoordinateReferenceSystem expected,
            final CoordinateReferenceSystem actual)
    {
        if ((expected instanceof SingleCRS) && (actual instanceof SingleCRS)) {
            final Datum datum = ((SingleCRS) expected).getDatum();
            if (datum != null && !Utilities.equalsIgnoreMetadata(datum, ((SingleCRS) actual).getDatum())) {
                throw new MismatchedDatumException(Resources.format(
                        Resources.Keys.IncompatibleDatum_2, datum.getName(), param));
            }
        }
    }

    /**
     * Concatenates to the given transform the operation needed for swapping and scaling the axes.
     * The two coordinate systems must implement the same GeoAPI coordinate system interface.
     * For example if {@code sourceCRS} uses a {@code CartesianCS}, then {@code targetCRS} must use
     * a {@code CartesianCS} too.
     *
     * @param  transform  the transform to which to concatenate axis changes.
     * @param  sourceCRS  the first CRS of the pair for which to check for axes changes.
     * @param  targetCRS  the second CRS of the pair for which to check for axes changes.
     * @param  interpDim  the number of dimensions of the interpolation CRS, or 0 if none.
     * @param  isSource   {@code true} for pre-concatenating the changes, or {@code false} for post-concatenating.
     * @param  factory    the factory to use for performing axis changes.
     */
    private static MathTransform swapAndScaleAxes(MathTransform transform,
            final CoordinateReferenceSystem sourceCRS,
            final CoordinateReferenceSystem targetCRS,
            final int interpDim, final boolean isSource,
            final MathTransformFactory factory) throws FactoryException
    {
        if (sourceCRS != null && targetCRS != null && sourceCRS != targetCRS) try {
            Matrix m = CoordinateSystems.swapAndScaleAxes(sourceCRS.getCoordinateSystem(),
                                                          targetCRS.getCoordinateSystem());
            if (!m.isIdentity()) {
                if (interpDim != 0) {
                    m = Matrices.createPassThrough(interpDim, m, 0);
                }
                final MathTransform s = factory.createAffineTransform(m);
                transform = factory.createConcatenatedTransform(isSource ? s : transform,
                                                                isSource ? transform : s);
            }
        } catch (IncommensurableException e) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2,
                    (isSource ? "sourceCRS" : "targetCRS"),
                    (isSource ?  sourceCRS  :  targetCRS).getName()), e);
        }
        return transform;
    }




    /*
     ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
     ┃                                                                                  ┃
     ┃                               XML support with JAXB                              ┃
     ┃                                                                                  ┃
     ┃        The following methods are invoked by JAXB using reflection (even if       ┃
     ┃        they are private) or are helpers for other methods invoked by JAXB.       ┃
     ┃        Those methods can be safely removed if Geographic Markup Language         ┃
     ┃        (GML) support is not needed.                                              ┃
     ┃                                                                                  ┃
     ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
     */

    /**
     * Constructs a new object in which every attributes are set to a null value.
     * <strong>This is not a valid object.</strong> This constructor is strictly
     * reserved to JAXB, which will assign values to the fields using reflection.
     */
    private DefaultConversion() {
    }
}
