/*
 * 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 java.util.Arrays;
import java.util.Objects;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.PassThroughOperation;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.CompoundCRS;
import org.apache.sis.referencing.operation.transform.MathTransforms;
import org.apache.sis.referencing.operation.transform.PassThroughTransform;
import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.metadata.MetadataUtilities;
import org.apache.sis.util.UnsupportedImplementationException;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.io.wkt.FormattableObject;
import org.apache.sis.io.wkt.Formatter;

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


/**
 * Specifies that a subset of a coordinate tuple is subject to a specific coordinate operation.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 0.7
 * @since   0.6
 * @module
 */
@XmlType(name = "PassThroughOperationType", propOrder = {
    "indices",
    "operation"
})
@XmlRootElement(name = "PassThroughOperation")
public class DefaultPassThroughOperation extends AbstractCoordinateOperation implements PassThroughOperation {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = 4308173919747248695L;

    /**
     * The operation to apply on the subset of a coordinate tuple.
     *
     * <p><b>Consider this field as final!</b>
     * This field is modified only at unmarshalling time by {@link #setOperation(CoordinateOperation)}</p>
     *
     * @see #getOperation()
     */
    private CoordinateOperation operation;

    /**
     * Constructs a pass-through operation from a set of properties.
     * The properties given in argument follow the same rules than 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>
     * </table>
     *
     * @param  properties               the properties to be given to the identified object.
     * @param  sourceCRS                the source CRS.
     * @param  targetCRS                the target CRS.
     * @param  operation                the operation to apply on the subset of a coordinate tuple.
     * @param  firstAffectedCoordinate  index of the first affected coordinate.
     * @param  numTrailingCoordinates   number of trailing coordinates to pass through.
     */
    public DefaultPassThroughOperation(final Map<String,?>            properties,
                                       final CoordinateReferenceSystem sourceCRS,
                                       final CoordinateReferenceSystem targetCRS,
                                       final CoordinateOperation       operation,
                                       final int firstAffectedCoordinate,
                                       final int numTrailingCoordinates)
    {
        super(properties, sourceCRS, targetCRS, null, MathTransforms.passThrough(
                firstAffectedCoordinate, operation.getMathTransform(), numTrailingCoordinates));
        ArgumentChecks.ensureNonNull("operation", operation);
        this.operation = operation;
    }

    /**
     * Creates a new coordinate operation 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  operation  the coordinate operation to copy.
     *
     * @see #castOrCopy(PassThroughOperation)
     */
    protected DefaultPassThroughOperation(final PassThroughOperation operation) {
        super(operation);
        this.operation = operation.getOperation();
    }

    /**
     * Returns a SIS coordinate operation implementation with the values of the given arbitrary implementation.
     * If the given object is already an instance of {@code DefaultPassThroughOperation}, then it is returned
     * unchanged. Otherwise a new {@code DefaultPassThroughOperation} instance is created using the
     * {@linkplain #DefaultPassThroughOperation(PassThroughOperation) 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.
     *
     * @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 DefaultPassThroughOperation castOrCopy(final PassThroughOperation object) {
        return (object == null) || (object instanceof DefaultPassThroughOperation)
                ? (DefaultPassThroughOperation) object : new DefaultPassThroughOperation(object);
    }

    /**
     * Returns the GeoAPI interface implemented by this class.
     * The SIS implementation returns {@code PassThroughOperation.class}.
     *
     * <div class="note"><b>Note for implementers:</b>
     * Subclasses usually do not need to override this method since GeoAPI does not define {@code PassThroughOperation}
     * sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with their
     * own set of interfaces.</div>
     *
     * @return {@code PassThroughOperation.class} or a user-defined sub-interface.
     */
    @Override
    public Class<? extends PassThroughOperation> getInterface() {
        return PassThroughOperation.class;
    }

    /**
     * Returns the operation to apply on the subset of a coordinate tuple.
     *
     * @return the operation to apply on the subset of a coordinate tuple.
     *
     * @see PassThroughTransform#getSubTransform()
     */
    @Override
    @XmlElement(name = "coordOperation", required = true)
    public CoordinateOperation getOperation() {
        return operation;
    }

    /**
     * Returns the ordered sequence of indices in a source coordinate tuple of the coordinates
     * affected by this pass-through operation.
     *
     * @return zero-based indices of the modified source coordinates.
     *
     * @see PassThroughTransform#getModifiedCoordinates()
     */
    @Override
    public int[] getModifiedCoordinates() {
        final MathTransform transform = super.getMathTransform();
        if (transform instanceof PassThroughTransform) {
            return ((PassThroughTransform) transform).getModifiedCoordinates();
        } else {
            /*
             * Should not happen with objects created by public methods since the constructor created the transform
             * itself. However may happen with operations parsed from GML. As a fallback, search in the components
             * of CompoundCRS. This is not a universal fallback, but work for the most straightforward cases.
             */
            final CoordinateReferenceSystem sourceCRS = super.getSourceCRS();
            if (sourceCRS instanceof CompoundCRS) {
                int firstAffectedCoordinate = 0;
                final CoordinateReferenceSystem search = operation.getSourceCRS();
                for (final CoordinateReferenceSystem c : ((CompoundCRS) sourceCRS).getComponents()) {
                    final int dim = ReferencingUtilities.getDimension(c);
                    if (c == search) {
                        final int[] indices = new int[dim];
                        for (int i=0; i<dim; i++) {
                            indices[i] = firstAffectedCoordinate + i;
                        }
                        return indices;
                    }
                    firstAffectedCoordinate += dim;
                }
            }
            throw new UnsupportedImplementationException(transform.getClass());
        }
    }

    /**
     * Compares this concatenated operation with the specified object for equality. If the {@code mode} argument
     * is {@link ComparisonMode#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}.
     *
     * @return {@inheritDoc}
     */
    @Override
    public boolean equals(final Object object, final ComparisonMode mode) {
        if (object == this) {
            return true;                                                    // Slight optimization.
        }
        if (super.equals(object, mode)) {
            if (mode == ComparisonMode.STRICT) {
                return Objects.equals(operation, ((DefaultPassThroughOperation) object).operation);
            } else {
                return deepEquals(getOperation(), ((PassThroughOperation) object).getOperation(), mode);
            }
        }
        return false;
    }

    /**
     * {@inheritDoc}
     *
     * @return {@inheritDoc}
     */
    @Override
    protected long computeHashCode() {
        return super.computeHashCode() + 31 * operation.hashCode();
    }

    /**
     * Formats this coordinate operation in a pseudo-Well Known Text (WKT) format.
     * Current format is specific to Apache SIS and may change in any future version
     * if a standard format for pass through operations is defined.
     *
     * @param  formatter  the formatter to use.
     * @return currently {@code "PassThroughOperation"} (may change in any future version).
     *
     * @since 0.7
     */
    @Override
    protected String formatTo(final Formatter formatter) {
        super.formatTo(formatter);
        formatter.append(new FormattableObject() {
            @Override protected String formatTo(final Formatter formatter) {
                for (final int i : getModifiedCoordinates()) {
                    formatter.append(i);
                }
                return "ModifiedCoordinates";
            }
        });
        formatter.newLine();
        formatter.append(castOrCopy(getOperation()));
        formatter.setInvalidWKT(this, null);
        return "PassThroughOperation";
    }




    //////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                  ////////
    ////////                               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.
     */
    private DefaultPassThroughOperation() {
        /*
         * A sub-operation 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 CC_CoordinateOperation adapter does some verifications.
         */
    }

    /**
     * Invoked by JAXB at unmarshalling time for setting the coordinate operation
     * applied on the subset of a coordinate tuple.
     *
     * @see #getOperation()
     */
    private void setOperation(final CoordinateOperation op) {
        if (operation == null) {
            operation = op;
        } else {
            MetadataUtilities.propertyAlreadySet(DefaultPassThroughOperation.class, "setOperation", "coordOperation");
        }
    }

    /**
     * Invoked by JAXB at marshalling time for getting the modified coordinates.
     * This method converts the zero-based indices to 1-based indices.
     *
     * @see #getModifiedCoordinates()
     */
    @XmlElement(name = "modifiedCoordinate", required = true)
    private int[] getIndices() {
        final int[] indices = getModifiedCoordinates();
        for (int i=0; i<indices.length; i++) {
            indices[i]++;
        }
        return indices;
    }

    /**
     * Invoked by JAXB at unmarshalling time for setting the modified coordinates.
     */
    private void setIndices(final int[] coordinates) {
        String missing = "sourceCRS";
        final CoordinateReferenceSystem sourceCRS = super.getSourceCRS();
        if (sourceCRS != null) {
            missing = "modifiedCoordinate";
            if (coordinates != null && coordinates.length != 0) {
                missing = "coordOperation";
                if (operation != null) {
                    for (int i=1; i<coordinates.length; i++) {
                        final int previous = coordinates[i-1];
                        if (previous < 1 || coordinates[i] != previous + 1) {
                            throw new IllegalArgumentException(Errors.format(
                                    Errors.Keys.CanNotAssign_2, missing, Arrays.toString(coordinates)));
                        }
                    }
                    transform = MathTransforms.passThrough(coordinates[0] - 1, operation.getMathTransform(),
                            ReferencingUtilities.getDimension(sourceCRS) - coordinates[coordinates.length - 1]);
                    return;
                }
            }
        }
        throw new IllegalStateException(Errors.format(Errors.Keys.MissingComponentInElement_2, missing, "PassThroughOperation"));
    }
}
