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

import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.ValidationException;
import org.opengis.util.FactoryException;
import org.opengis.referencing.datum.Datum;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.geometry.MismatchedDimensionException;
import org.apache.sis.referencing.operation.DefaultConversion;
import org.apache.sis.internal.jaxb.referencing.CC_Conversion;
import org.apache.sis.internal.referencing.ReferencingFactoryContainer;
import org.apache.sis.internal.metadata.MetadataUtilities;
import org.apache.sis.internal.metadata.Identifiers;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.system.Semaphores;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;

import static org.apache.sis.util.Utilities.deepEquals;


/**
 * A coordinate reference system that is defined by its coordinate
 * {@linkplain org.apache.sis.referencing.operation.DefaultConversion conversion} from another CRS
 * (not by a {@linkplain org.apache.sis.referencing.datum.AbstractDatum datum}).
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 1.2
 *
 * @param <C>  the conversion type, either {@code Conversion} or {@code Projection}.
 *
 * @since 0.6
 * @module
 */
@XmlType(name = "AbstractGeneralDerivedCRSType")
@XmlRootElement(name = "AbstractGeneralDerivedCRS")
@XmlSeeAlso({
    DefaultDerivedCRS.class,
    DefaultProjectedCRS.class
})
abstract class AbstractDerivedCRS<C extends Conversion> extends AbstractCRS implements GeneralDerivedCRS {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -175151161496419854L;

    /**
     * The conversion from the {@linkplain #getBaseCRS() base CRS} to this CRS.
     * The base CRS of this {@code GeneralDerivedCRS} is {@link Conversion#getSourceCRS()}.
     *
     * <p><b>Consider this field as final!</b>
     * This field is modified only at unmarshalling time by {@link #setConversionFromBase(Conversion)}</p>
     *
     * @see #getConversionFromBase()
     */
    private C conversionFromBase;

    /**
     * Creates a derived CRS from a defining conversion.
     * The properties given in argument follow the same rules than for the
     * {@linkplain AbstractCRS#AbstractCRS(Map, CoordinateSystem) super-class constructor}.
     *
     * @param  properties  the properties to be given to the new derived CRS object.
     * @param  baseCRS     coordinate reference system to base the derived CRS on.
     * @param  conversion  the defining conversion from a normalized base to a normalized derived CRS.
     * @param  derivedCS   the coordinate system for the derived CRS. The number of axes must match
     *                     the target dimension of the {@code baseToDerived} transform.
     * @throws MismatchedDimensionException if the source and target dimensions of {@code baseToDerived}
     *         do not match the dimensions of {@code base} and {@code derivedCS} respectively.
     */
    AbstractDerivedCRS(final Map<String,?>    properties,
                       final SingleCRS        baseCRS,
                       final Conversion       conversion,
                       final CoordinateSystem derivedCS)
            throws MismatchedDimensionException
    {
        super(properties, derivedCS);
        ArgumentChecks.ensureNonNull("baseCRS", baseCRS);
        ArgumentChecks.ensureNonNull("conversion", conversion);
        ArgumentChecks.ensureDimensionsMatch("baseToDerived",
                baseCRS.getCoordinateSystem().getDimension(),
                derivedCS.getDimension(),
                conversion.getMathTransform());
        conversionFromBase = createConversionFromBase(properties, baseCRS, conversion);
    }

    /**
     * For {@link DefaultDerivedCRS#DefaultDerivedCRS(Map, SingleCRS, CoordinateReferenceSystem, OperationMethod,
     * MathTransform, CoordinateSystem)} constructor only (<strong>not legal for {@code ProjectedCRS}</strong>).
     */
    @SuppressWarnings("unchecked")
    AbstractDerivedCRS(final Map<String,?>             properties,
                       final SingleCRS                 baseCRS,
                       final CoordinateReferenceSystem interpolationCRS,
                       final OperationMethod           method,
                       final MathTransform             baseToDerived,
                       final CoordinateSystem          derivedCS)
            throws MismatchedDimensionException
    {
        super(properties, derivedCS);
        ArgumentChecks.ensureNonNull("baseCRS", baseCRS);
        ArgumentChecks.ensureNonNull("method", method);
        ArgumentChecks.ensureNonNull("baseToDerived", baseToDerived);
        conversionFromBase = (C) new DefaultConversion(   // Cast to (C) is valid only for DefaultDerivedCRS.
                ConversionKeys.unprefix(properties), baseCRS, this, interpolationCRS, method, baseToDerived);
    }

    /**
     * Constructs a new coordinate reference system with the same values than 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  crs  the coordinate reference system to copy.
     */
    AbstractDerivedCRS(final GeneralDerivedCRS crs) {
        super(crs);
        conversionFromBase = createConversionFromBase(null, crs.getBaseCRS(), crs.getConversionFromBase());
    }

    /**
     * Creates the conversion instance to associate with this {@code AbstractDerivedCRS}.
     *
     * <p><b>WARNING:</b> this method is invoked at construction time and will invoke indirectly
     * (through {@link DefaultConversion}) the {@link #getCoordinateSystem()} method on {@code this}.
     * Consequently this method shall be invoked only after the construction of this {@code AbstractDerivedCRS}
     * instance is advanced enough for allowing the {@code getCoordinateSystem()} method to execute.
     * Subclasses may consider to make the {@code getCoordinateSystem()} method final for better guarantees.</p>
     */
    private C createConversionFromBase(final Map<String,?> properties, final SingleCRS baseCRS, final Conversion conversion) {
        MathTransformFactory factory = null;
        if (properties != null) {
            factory = (MathTransformFactory) properties.get(ReferencingFactoryContainer.MT_FACTORY);
        }
        if (factory == null) {
            factory = DefaultFactories.forBuildin(MathTransformFactory.class);
        }
        try {
            return DefaultConversion.castOrCopy(conversion).specialize(getConversionType(), baseCRS, this, factory);
        } catch (FactoryException e) {
            throw new IllegalArgumentException(Errors.getResources(properties).getString(
                    Errors.Keys.IllegalArgumentValue_2, "conversion", conversion.getName()), e);
        }
    }

    /**
     * Returns the type of conversion associated to this {@code AbstractDerivedCRS}.
     *
     * <p><b>WARNING:</b> this method is invoked (indirectly) at construction time.
     * Consequently it shall return a constant value - this method is not allowed to
     * depend on the object state.</p>
     */
    abstract Class<C> getConversionType();

    /**
     * Returns the GeoAPI interface implemented by this class.
     */
    @Override
    public abstract Class<? extends GeneralDerivedCRS> getInterface();

    /**
     * Returns the datum of the {@linkplain #getBaseCRS() base CRS}.
     *
     * @return the datum of the base CRS.
     */
    @Override
    public abstract Datum getDatum();

    /**
     * Returns the conversion from the {@linkplain #getBaseCRS() base CRS} to this CRS.
     *
     * @return the conversion to this CRS.
     */
    @Override
    @XmlElement(name = "conversion", required = true)
    public C getConversionFromBase() {
        return conversionFromBase;
    }

    /**
     * Compares this coordinate reference system with the specified object for equality.
     *
     * @param  object  the object to compare to {@code this}.
     * @param  mode    {@link ComparisonMode#STRICT STRICT} for performing a strict comparison, or
     *                 {@link ComparisonMode#IGNORE_METADATA IGNORE_METADATA} for comparing only
     *                 properties relevant to coordinate transformations.
     * @return {@code true} if both objects are equal.
     */
    @Override
    public boolean equals(final Object object, final ComparisonMode mode) {
        if (object == this) {
            return true;
        }
        if (super.equals(object, mode)) {
            final boolean strict = (mode == ComparisonMode.STRICT);
            /*
             * Avoid never-ending recursivity: Conversion has a `targetCRS` field (inherited from
             * the AbstractCoordinateOperation super-class) that is set to this AbstractDerivedCRS.
             *
             * Do NOT compare the baseCRS explicitly. This is done implicitely in the comparison of the Conversion
             * objects, since (this.baseCRS == Conversion.sourceCRS) in Apache SIS.  The reason why we delegate the
             * comparison of that CRS to the Conversion object is because we want to ignore the baseCRS axes if the
             * mode said to ignore metadata, but ignoring axis order and units has implication on the MathTransform
             * instances to compare.  The AbstractCoordinateOperation.equals(…) method implementation handles those
             * cases.
             */
            if (Semaphores.queryAndSet(Semaphores.CONVERSION_AND_CRS)) {
                return true;
            } else try {
                return deepEquals(strict ? conversionFromBase : getConversionFromBase(),
                                  strict ? ((AbstractDerivedCRS) object).conversionFromBase
                                         :  ((GeneralDerivedCRS) object).getConversionFromBase(), mode);
            } finally {
                Semaphores.clear(Semaphores.CONVERSION_AND_CRS);
            }
        }
        return false;
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    protected long computeHashCode() {
        /*
         * Do not invoke `conversionFromBase.hashCode()` in order to avoid a never-ending loop.
         * This is because Conversion inherits a `sourceCRS` field from the CoordinateOperation
         * parent type, which is set to this DerivedCRS. Checking the OperationMethod does not
         * work neither for the reason documented inside the AbstractSingleOperation.equals(…)
         * method body. The MathTransform is our best discriminant.
         */
        return super.computeHashCode()
               + 31 * conversionFromBase.getSourceCRS().hashCode()
               + 37 * conversionFromBase.getMathTransform().hashCode();
    }




    //////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                  ////////
    ////////                               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 reflexion.
     */
    AbstractDerivedCRS() {
    }

    /**
     * Invoked by JAXB at unmarshalling time for setting the <cite>defining conversion</cite>.
     * At this state, the given conversion has null {@code sourceCRS} and {@code targetCRS}.
     * Those CRS will be set later, in {@link #afterUnmarshal(Unmarshaller, Object)}.
     */
    private void setConversionFromBase(final C conversion) {
        if (conversionFromBase == null) {
            conversionFromBase = conversion;
        } else {
            MetadataUtilities.propertyAlreadySet(AbstractDerivedCRS.class, "setConversionFromBase", "conversion");
        }
    }

    /**
     * Stores a temporary association to the given base CRS.  This method shall be invoked only
     * <strong>after</strong> the call to {@link #setConversionFromBase(Conversion)}, otherwise
     * an exception will be thrown.
     *
     * <p>The given base CRS will not be stored in this {@code AbstractDerivedCRS} instance now,
     * but in another temporary location. The reason is that we need the coordinate system (CS)
     * before we can set the {@code baseCRS} in its final location, but the CS is not yet known
     * when this method is invoked.</p>
     *
     * @param  name  the property name, used only in case of error message to format.
     * @throws IllegalStateException if the base CRS can not be set.
     */
    @SuppressWarnings("unchecked")
    final void setBaseCRS(final String name, final SingleCRS baseCRS) {
        if (conversionFromBase != null) {
            final SingleCRS previous = CC_Conversion.setBaseCRS(conversionFromBase, baseCRS);
            if (previous != null) {
                CC_Conversion.setBaseCRS(conversionFromBase, previous);   // Temporary location.
                MetadataUtilities.propertyAlreadySet(AbstractDerivedCRS.class, "setBaseCRS", name);
            }
        } else {
            throw new IllegalStateException(Errors.format(Errors.Keys.MissingComponentInElement_2, getInterface(), "conversion"));
        }
    }

    /**
     * Invoked by JAXB after all elements have been unmarshalled. At this point we should have the
     * coordinate system (CS). The CS information is required by {@code createConversionFromBase(…)}
     * in order to create a {@link MathTransform} with correct axis swapping and unit conversions.
     */
    private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) throws ValidationException {
        String property = "conversion";
        if (conversionFromBase != null) {
            final SingleCRS baseCRS = CC_Conversion.setBaseCRS(conversionFromBase, null);  // Clear the temporary value now.
            property = "coordinateSystem";
            if (super.getCoordinateSystem() != null) {
                property = "baseCRS";
                if (baseCRS != null) {
                    conversionFromBase = createConversionFromBase(null, baseCRS, conversionFromBase);
                    return;
                }
            }
        }
        /*
         * If we reach this point, we failed to update the conversion. The `baseCRS` information will be lost
         * and call to `getConversionFromBase()` will throw a ClassCastException if this instance is actually
         * a ProjectedCRS (because of the method overriding with return type covariance).
         */
        throw new ValidationException(Identifiers.missingValueForProperty(getName(), property));
    }
}
