/*
 * 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 java.util.EnumMap;
import java.util.Objects;
import java.util.ConcurrentModificationException;
import javax.measure.Unit;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import org.opengis.referencing.datum.Datum;
import org.opengis.referencing.cs.AffineCS;
import org.opengis.referencing.cs.CartesianCS;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.metadata.MetadataUtilities;
import org.apache.sis.referencing.AbstractReferenceSystem;
import org.apache.sis.referencing.IdentifiedObjects;
import org.apache.sis.referencing.cs.AxesConvention;
import org.apache.sis.referencing.cs.AbstractCS;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.io.wkt.Convention;
import org.apache.sis.io.wkt.Formatter;

import static org.apache.sis.util.Utilities.deepEquals;
import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
import static org.apache.sis.internal.referencing.WKTUtilities.toFormattable;


/**
 * Coordinate reference system, defined by a {@linkplain AbstractCS coordinate system}
 * and (usually) a {@linkplain org.apache.sis.referencing.datum.AbstractDatum datum}.
 * A coordinate reference system (CRS) consists of an ordered sequence of
 * {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis coordinate system axes}
 * that are related to the earth through the datum.
 * Most coordinate reference system do not move relative to the earth, except for
 * {@linkplain DefaultEngineeringCRS engineering coordinate reference systems}
 * defined on moving platforms such as cars, ships, aircraft, and spacecraft.
 *
 * <p>Coordinate reference systems can have an arbitrary number of dimensions.
 * The actual dimension of a given instance can be determined as below:</p>
 *
 * {@preformat java
 *   int dimension = crs.getCoordinateSystem().getDimension();
 * }
 *
 * However most subclasses restrict the allowed number of dimensions.
 *
 * <h2>Instantiation</h2>
 * This class is conceptually <cite>abstract</cite>, even if it is technically possible to instantiate it.
 * Typical applications should create instances of the most specific subclass prefixed by {@code Default} instead.
 * An exception to this rule may occur when it is not possible to identify the exact CRS type.
 *
 * <h2>Immutability and thread safety</h2>
 * This base 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. Most SIS subclasses and related classes are immutable under similar
 * conditions. This means that unless otherwise noted in the javadoc, {@code CoordinateReferenceSystem} 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 0.7
 *
 * @see AbstractCS
 * @see org.apache.sis.referencing.datum.AbstractDatum
 *
 * @since 0.4
 * @module
 */
@XmlType(name = "AbstractCRSType", propOrder = {
    "domainOfValidity",
    "scope"
})
@XmlRootElement(name = "AbstractCRS")
@XmlSeeAlso({
    AbstractDerivedCRS.class,
    DefaultGeodeticCRS.class,
    DefaultVerticalCRS.class,
    DefaultTemporalCRS.class,
    DefaultParametricCRS.class,
    DefaultEngineeringCRS.class,
    DefaultImageCRS.class,
    DefaultCompoundCRS.class
})
public class AbstractCRS extends AbstractReferenceSystem implements CoordinateReferenceSystem {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -7433284548909530047L;

    /**
     * The coordinate system.
     *
     * <p><b>Consider this field as final!</b>
     * This field is modified only at unmarshalling time by {@link #setCoordinateSystem(String, CoordinateSystem)}</p>
     *
     * @see #getCoordinateSystem()
     */
    private CoordinateSystem coordinateSystem;

    /**
     * Other coordinate reference systems computed from this CRS by the application of an axes convention.
     * Created only when first needed.
     *
     * @see #forConvention(AxesConvention)
     */
    private transient Map<AxesConvention,AbstractCRS> forConvention;

    /**
     * Creates a coordinate reference system from the given properties and coordinate system.
     * The properties given in argument follow the same rules than for the
     * {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) 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#ALIAS_KEY}</td>
     *     <td>{@link org.opengis.util.GenericName} or {@link CharSequence} (optionally as array)</td>
     *     <td>{@link #getAlias()}</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.IdentifiedObject#REMARKS_KEY}</td>
     *     <td>{@link org.opengis.util.InternationalString} or {@link String}</td>
     *     <td>{@link #getRemarks()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.ReferenceSystem#DOMAIN_OF_VALIDITY_KEY}</td>
     *     <td>{@link org.opengis.metadata.extent.Extent}</td>
     *     <td>{@link #getDomainOfValidity()}</td>
     *   </tr>
     *   <tr>
     *     <td>{@value org.opengis.referencing.ReferenceSystem#SCOPE_KEY}</td>
     *     <td>{@link org.opengis.util.InternationalString} or {@link String}</td>
     *     <td>{@link #getScope()}</td>
     *   </tr>
     * </table>
     *
     * @param properties  the properties to be given to the coordinate reference system.
     * @param cs          the coordinate system.
     */
    public AbstractCRS(final Map<String,?> properties, final CoordinateSystem cs) {
        super(properties);
        ensureNonNull("cs", cs);
        coordinateSystem = cs;
    }

    /**
     * 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.
     *
     * @see #castOrCopy(CoordinateReferenceSystem)
     */
    protected AbstractCRS(final CoordinateReferenceSystem crs) {
        super(crs);
        coordinateSystem = crs.getCoordinateSystem();
    }

    /**
     * Returns a SIS coordinate reference system 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 an instance of
     *       {@link org.opengis.referencing.crs.GeodeticCRS} (including the
     *       {@link org.opengis.referencing.crs.GeographicCRS} and
     *       {@link org.opengis.referencing.crs.GeocentricCRS} subtypes),
     *       {@link org.opengis.referencing.crs.VerticalCRS},
     *       {@link org.opengis.referencing.crs.TemporalCRS},
     *       {@link org.opengis.referencing.crs.EngineeringCRS},
     *       {@link org.opengis.referencing.crs.ImageCRS} or
     *       {@link org.apache.sis.referencing.cs.DefaultCompoundCS},
     *       then this method delegates to the {@code castOrCopy(…)} method of the corresponding SIS subclass.
     *       Note that if the given object implements more than one of the above-cited interfaces,
     *       then the {@code castOrCopy(…)} method to be used is unspecified.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code AbstractCRS}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code AbstractCRS} instance is created using the
     *       {@linkplain #AbstractCRS(CoordinateReferenceSystem) copy constructor}
     *       and returned. Note that this is a <cite>shallow</cite> copy operation, since 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 AbstractCRS castOrCopy(final CoordinateReferenceSystem object) {
        return SubTypes.castOrCopy(object);
    }

    /**
     * Returns the GeoAPI interface implemented by this class.
     * The default implementation returns {@code CoordinateReferenceSystem.class}.
     * Subclasses implementing a more specific GeoAPI interface shall override this method.
     *
     * @return the coordinate reference system interface implemented by this class.
     */
    @Override
    public Class<? extends CoordinateReferenceSystem> getInterface() {
        return CoordinateReferenceSystem.class;
    }

    /**
     * Returns the datum, or {@code null} if none.
     *
     * This property does not exist in {@code CoordinateReferenceSystem} interface — it is defined in the
     * {@link SingleCRS} sub-interface instead. But Apache SIS does not define an {@code AbstractSingleCRS} class
     * in order to simplify our class hierarchy, so we provide a datum getter in this class has a hidden property.
     * Subclasses implementing {@code SingleCRS} (basically all SIS subclasses except {@link DefaultCompoundCRS})
     * will override this method with public access and more specific return type.
     *
     * @return the datum, or {@code null} if none.
     */
    Datum getDatum() {
        /*
         * User could provide his own CRS implementation outside this SIS package, so we have
         * to check for SingleCRS interface. But all SIS classes override this implementation.
         */
        return (this instanceof SingleCRS) ? ((SingleCRS) this).getDatum() : null;
    }

    /**
     * Returns the coordinate system.
     *
     * @return the coordinate system.
     */
    @Override
    public CoordinateSystem getCoordinateSystem() {
        return coordinateSystem;
    }

    /**
     * Returns the coordinate system if it is of the given type, or {@code null} otherwise.
     * This method is invoked by subclasses that can accept more than one CS type.
     */
    @SuppressWarnings("unchecked")
    final <T extends CoordinateSystem> T getCoordinateSystem(final Class<T> type) {
        final CoordinateSystem cs = coordinateSystem;
        if (type.isInstance(cs)) {
            // Special case for AfficeCS: must ensure that the cs is not the CartesianCS subtype.
            if (type != AffineCS.class || !(cs instanceof CartesianCS)) {
                return (T) cs;
            }
        }
        return null;
    }

    /**
     * Returns the existing CRS for the given convention, or {@code null} if none.
     */
    final AbstractCRS getCached(final AxesConvention convention) {
        assert Thread.holdsLock(this);
        return (forConvention != null) ? forConvention.get(convention) : null;
    }

    /**
     * Sets the CRS for the given axes convention.
     *
     * @param  crs  the CRS to cache.
     * @return the cached CRS. May be different than the given {@code crs} if an existing instance has been found.
     */
    final AbstractCRS setCached(final AxesConvention convention, AbstractCRS crs) {
        assert Thread.holdsLock(this);
        if (forConvention == null) {
            forConvention = new EnumMap<>(AxesConvention.class);
        } else if (crs != this) {
            for (final AbstractCRS existing : forConvention.values()) {
                if (crs.equals(existing)) {
                    crs = existing;
                    break;
                }
            }
        }
        if (forConvention.put(convention, crs) != null) {
            throw new ConcurrentModificationException();    // Should never happen, unless we have a synchronization bug.
        }
        return crs;
    }

    /**
     * Returns a coordinate reference system equivalent to this one but with axes rearranged according the given
     * convention. If this CRS is already compatible with the given convention, then this method returns {@code this}.
     *
     * @param  convention  the axes convention for which a coordinate reference system is desired.
     * @return a coordinate reference system compatible with the given convention (may be {@code this}).
     *
     * @see AbstractCS#forConvention(AxesConvention)
     */
    public synchronized AbstractCRS forConvention(final AxesConvention convention) {
        ensureNonNull("convention", convention);
        AbstractCRS crs = getCached(convention);
        if (crs == null) {
            final AbstractCS cs = AbstractCS.castOrCopy(coordinateSystem);
            final AbstractCS candidate = cs.forConvention(convention);
            if (candidate == cs) {
                crs = this;
            } else {
                crs = createSameType(IdentifiedObjects.getProperties(this, IDENTIFIERS_KEY), candidate);
            }
            crs = setCached(convention, crs);
        }
        return crs;
    }

    /**
     * Returns a coordinate reference system of the same type than this CRS but with different axes.
     * This method shall be overridden by all {@code AbstractCRS} subclasses in this package.
     */
    AbstractCRS createSameType(final Map<String,?> properties, final CoordinateSystem cs) {
        return new AbstractCRS(properties, cs);
    }

    /**
     * Compares this coordinate reference system with the specified object for equality.
     * If the {@code mode} argument value is {@link ComparisonMode#STRICT STRICT} or
     * {@link ComparisonMode#BY_CONTRACT BY_CONTRACT}, then all available properties are
     * compared including the {@linkplain #getDomainOfValidity() domain of validity} and
     * the {@linkplain #getScope() scope}.
     *
     * @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 (super.equals(object, mode)) {
            final Datum datum = getDatum();
            switch (mode) {
                case STRICT: {
                    final AbstractCRS that = (AbstractCRS) object;
                    return Objects.equals(datum, that.getDatum()) &&
                           Objects.equals(coordinateSystem, that.coordinateSystem);
                }
                default: {
                    return deepEquals(datum, (object instanceof SingleCRS) ? ((SingleCRS) object).getDatum() : null, mode) &&
                           deepEquals(getCoordinateSystem(), ((CoordinateReferenceSystem) object).getCoordinateSystem(), mode);
                }
            }
        }
        return false;
    }

    /**
     * Invoked by {@code hashCode()} for computing the hash code when first needed.
     * See {@link org.apache.sis.referencing.AbstractIdentifiedObject#computeHashCode()}
     * for more information.
     *
     * @return the hash code value. This value may change in any future Apache SIS version.
     */
    @Override
    protected long computeHashCode() {
        return super.computeHashCode() + Objects.hash(getDatum(), coordinateSystem);
    }

    /**
     * Formats the inner part of the <cite>Well Known Text</cite> (WKT) representation of this CRS.
     * The default implementation writes the following elements in WKT 2 format:
     *
     * <ul>
     *   <li>The object {@linkplain #getName() name}.</li>
     *   <li>The datum, if any.</li>
     *   <li>All {@linkplain #getCoordinateSystem() coordinate system}'s axis.</li>
     *   <li>The unit if all axes use the same unit, or nothing otherwise.</li>
     * </ul>
     *
     * The WKT 1 format is similar to the WKT 2 one with two differences:
     * <ul>
     *   <li>Units are formatted before the axes instead than after the axes.</li>
     *   <li>If no unit can be formatted because not all axes use the same unit, then the WKT is
     *       {@linkplain Formatter#setInvalidWKT(IdentifiedObject, Exception) flagged as invalid}.</li>
     * </ul>
     *
     * @return {@inheritDoc}
     *
     * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
     * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy WKT 1</a>
     */
    @Override
    protected String formatTo(final Formatter formatter) {
        final String keyword = super.formatTo(formatter);
        formatter.newLine();
        formatter.append(toFormattable(getDatum()));
        formatter.newLine();
        final Convention convention = formatter.getConvention();
        final boolean isWKT1 = convention.majorVersion() == 1;
        if (isWKT1 || convention == Convention.INTERNAL || !isBaseCRS(formatter)) {
            final CoordinateSystem cs = getCoordinateSystem();
            formatCS(formatter, cs, ReferencingUtilities.getUnit(cs), isWKT1);
        }
        return keyword;
    }

    /**
     * Returns {@code true} if the given formatter is in the process of formatting the base CRS of an
     * {@link AbstractDerivedCRS}. In such case, the coordinate system axes shall not be formatted.
     *
     * <p>This method should return {@code true} when {@code this} CRS is the value returned by
     * {@link GeneralDerivedCRS#getBaseCRS()} (typically {@link AbstractDerivedCRS#getBaseCRS()}).
     * Since the base CRS is the only CRS enclosed in derived CRS, we should have no ambiguity
     * (assuming that the user did not created some weird subclass).</p>
     *
     * <p>This method should be invoked for WKT 2 formatting only.</p>
     */
    static boolean isBaseCRS(final Formatter formatter) {
        return formatter.getEnclosingElement(1) instanceof GeneralDerivedCRS;
    }

    /**
     * Formats the given coordinate system.
     *
     * <p>In WKT 2 format, this method should not be invoked if {@link #isBaseCRS(Formatter)} returned {@code true}
     * because ISO 19162 excludes the coordinate system definition in base CRS. Note however that WKT 1 includes the
     * coordinate systems. The SIS-specific {@link Convention#INTERNAL} formats also those coordinate systems.</p>
     *
     * <div class="note"><b>Note:</b> the {@code unit} and {@code isWKT1} arguments could be computed by this method,
     * but are requested in order to avoid computing them twice, because the caller usually have them anyway.</div>
     *
     * @param  formatter  the formatter where to append the coordinate system.
     * @param  cs         the coordinate system to append.
     * @param  unit       the value of {@code ReferencingUtilities.getUnit(cs)}.
     * @param  isWKT1     {@code true} if formatting WKT 1, or {@code false} for WKT 2.
     */
    final void formatCS(final Formatter formatter, final CoordinateSystem cs, final Unit<?> unit, final boolean isWKT1) {
        assert unit == ReferencingUtilities.getUnit(cs) : unit;
        assert (formatter.getConvention().majorVersion() == 1) == isWKT1 : isWKT1;
        assert isWKT1 || !isBaseCRS(formatter) || formatter.getConvention() == Convention.INTERNAL;    // Condition documented in javadoc.

        final Unit<?> oldUnit = formatter.addContextualUnit(unit);
        if (isWKT1) {                               // WKT 1 writes unit before axes, while WKT 2 writes them after axes.
            formatter.append(unit);
            if (unit == null) {
                formatter.setInvalidWKT(this, null);
            }
        } else {
            formatter.append(toFormattable(cs));    // WKT2 only, since the concept of CoordinateSystem was not explicit in WKT 1.
            formatter.indent(+1);
        }
        if (!isWKT1 || formatter.getConvention() != Convention.WKT1_IGNORE_AXES) {
            if (cs != null) {                       // Should never be null, except sometime temporarily during construction.
                final int dimension = cs.getDimension();
                for (int i=0; i<dimension; i++) {
                    formatter.newLine();
                    formatter.append(toFormattable(cs.getAxis(i)));
                }
            }
        }
        if (!isWKT1) {                              // WKT 2 writes unit after axes, while WKT 1 wrote them before axes.
            formatter.newLine();
            formatter.append(unit);
            formatter.indent(-1);
        }
        formatter.restoreContextualUnit(unit, oldUnit);
        formatter.newLine();                        // For writing the ID[…] element on its own line.
    }




    //////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                  ////////
    ////////                               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.
     */
    AbstractCRS() {
        super(org.apache.sis.internal.referencing.NilReferencingObject.INSTANCE);
        /*
         * The coordinate system is mandatory for SIS working. We do not verify its presence here
         * because the verification would have to be done in an 'afterMarshal(…)' method and throwing
         * an exception in that method causes the whole unmarshalling to fail. But the SC_CRS adapter
         * does some verifications.
         */
    }

    /**
     * Sets the coordinate system to the given value.
     * This method is indirectly invoked by JAXB at unmarshalling time.
     *
     * @param  name  the property name, used only in case of error message to format. Can be null for auto-detect.
     * @throws IllegalStateException if the coordinate system has already been set.
     */
    final void setCoordinateSystem(String name, final CoordinateSystem cs) {
        if (coordinateSystem == null) {
            coordinateSystem = cs;
        } else {
            if (name == null) {
                name = String.valueOf(ReferencingUtilities.toPropertyName(CoordinateSystem.class, cs.getClass()));
            }
            MetadataUtilities.propertyAlreadySet(AbstractCRS.class, "setCoordinateSystem", name);
        }
    }
}
