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

import java.util.Map;
import java.util.Collections;
import java.util.Arrays;
import java.util.Locale;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.measure.Unit;
import javax.measure.quantity.Angle;
import javax.measure.format.ParserException;
import org.opengis.util.FactoryException;
import org.opengis.util.NoSuchIdentifierException;
import org.opengis.parameter.ParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterNotFoundException;
import org.opengis.parameter.InvalidParameterValueException;
import org.opengis.referencing.operation.SingleOperation;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.opengis.referencing.operation.OperationMethod;
import org.apache.sis.internal.referencing.CoordinateOperations;
import org.apache.sis.internal.referencing.ReferencingFactoryContainer;
import org.apache.sis.internal.referencing.WKTKeywords;
import org.apache.sis.internal.util.Constants;
import org.apache.sis.math.DecimalFunctions;
import org.apache.sis.measure.UnitFormat;
import org.apache.sis.measure.Units;
import org.apache.sis.util.Numbers;
import org.apache.sis.util.resources.Errors;

import static org.apache.sis.util.ArgumentChecks.ensureNonNull;


/**
 * Well Known Text (WKT) parser for {@linkplain MathTransform math transform}s.
 * Note that while this base class is restricted to math transforms, subclasses may parse a wider range of objects.
 *
 * @author  Rémi Eve (IRD)
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @author  Rueben Schulz (UBC)
 * @version 1.0
 *
 * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Well Know Text specification</a>
 *
 * @since 0.6
 * @module
 */
class MathTransformParser extends AbstractParser {
    /**
     * The keywords for {@code ID} or {@code AUTHORITY} elements, as a static array because frequently used.
     */
    static final String[] ID_KEYWORDS = {WKTKeywords.Id, WKTKeywords.Authority};

    /**
     * The keywords of unit elements. Most frequently used keywords should be first.
     */
    private static final String[] UNIT_KEYWORDS = {
        WKTKeywords.Unit,   // Ignored since it does not allow us to know the quantity dimension.
        WKTKeywords.LengthUnit, WKTKeywords.AngleUnit, WKTKeywords.ScaleUnit, WKTKeywords.TimeUnit,
        WKTKeywords.ParametricUnit  // Ignored for the same reason than "Unit".
    };

    /**
     * The base units associated to the {@link #UNIT_KEYWORDS}, ignoring {@link WKTKeywords#Unit}.
     * For each {@code UNIT_KEYWORDS[i]} element, the associated base unit is {@code BASE_UNIT[i-1]}.
     */
    private static final Unit<?>[] BASE_UNITS = {
        Units.METRE, Units.RADIAN, Units.UNITY, Units.SECOND
    };

    /**
     * Some conversion factors applied to {@link #UNIT_KEYWORDS} for which rounding errors are found in practice.
     * Some Well Known Texts define factors with low accuracy, as in {@code ANGLEUNIT["degree", 0.01745329252]}.
     * This causes the parser to fail to recognize that the unit is degree and to convert angles with that factor.
     * This may result in surprising behavior like <a href="https://issues.apache.org/jira/browse/SIS-377">SIS-377</a>.
     * This array is a workaround for that problem, adding the missing accuracy to factors.
     * This workaround should be removed in a future version if we fix
     * <a href="https://issues.apache.org/jira/browse/SIS-433">SIS-433</a>.
     *
     * <p>Values in each array <strong>must</strong> be sorted in ascending order.</p>
     *
     * @see <a href="https://issues.apache.org/jira/browse/SIS-377">SIS-377</a>
     * @see <a href="https://issues.apache.org/jira/browse/SIS-433">SIS-433</a>
     */
    private static final double[][] CONVERSION_FACTORS = {
        {0.3048,                    // foot, declared for avoiding that unit to be confused with US survey foot.
         0.30480060960121924,       // US survey foot
         1609.3472186944375},       // US survey mile
        {Math.PI/(180*60*60),       // Arc-second:  4.84813681109536E-6
         Math.PI/(180*60),          // Arc-minute:  2.908882086657216E-4
         Math.PI/(200),             // Grad:        1.5707963267948967E-2
         Math.PI/(180)}             // Degree:      1.7453292519943295E-2
    };

    /**
     * The factories to use for creating math transforms and geodetic objects.
     */
    final ReferencingFactoryContainer factories;

    /**
     * The classification of the last math transform or projection parsed, or {@code null} if none.
     */
    private transient String classification;

    /**
     * The method for the last math transform passed, or {@code null} if none.
     *
     * @see #getOperationMethod()
     */
    private transient OperationMethod lastMethod;

    /**
     * Creates a parser for the given factory.
     *
     * <p><b>Maintenance note:</b> this constructor is invoked through reflection by
     * {@link org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory#createFromWKT(String)}.
     * Do not change the method signature even if it doesn't break the compilation, unless the reflection code
     * is also updated.</p>
     *
     * @param  mtFactory  the factory to use for creating {@link MathTransform} objects.
     */
    public MathTransformParser(final MathTransformFactory mtFactory) {
        this(Symbols.getDefault(), Collections.emptyMap(), null, null, null,
                new ReferencingFactoryContainer(null, null, null, null, null, mtFactory), null);
    }

    /**
     * Creates a parser using the specified set of symbols and factories.
     *
     * @param  symbols       the set of symbols to use.
     * @param  fragments     reference to the {@link WKTFormat#fragments} map, or an empty map if none.
     * @param  numberFormat  the number format provided by {@link WKTFormat}, or {@code null} for a default format.
     * @param  dateFormat    the date format provided by {@link WKTFormat}, or {@code null} for a default format.
     * @param  unitFormat    the unit format provided by {@link WKTFormat}, or {@code null} for a default format.
     * @param  factories     the factories to use for creating math transforms and geodetic objects.
     * @param  errorLocale   the locale for error messages (not for parsing), or {@code null} for the system default.
     */
    MathTransformParser(final Symbols symbols, final Map<String,Element> fragments,
            final NumberFormat numberFormat, final DateFormat dateFormat, final UnitFormat unitFormat,
            final ReferencingFactoryContainer factories, final Locale errorLocale)
    {
        super(symbols, fragments, numberFormat, dateFormat, unitFormat, errorLocale);
        this.factories = factories;
        ensureNonNull("factories", factories);
    }

    /**
     * Returns the name of the class providing the publicly-accessible {@code createFromWKT(String)} method.
     * This information is used for logging purpose only.
     */
    @Override
    String getPublicFacade() {
        return "org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory";
    }

    /**
     * Parses the next element in the specified <cite>Well Know Text</cite> (WKT) tree.
     *
     * @param  element  the element to be parsed.
     * @return the parsed object, or {@code null} if the element is not recognized.
     * @throws ParseException if the element can not be parsed.
     */
    @Override
    Object parseObject(final Element element) throws ParseException {
        return parseMathTransform(element, true);
    }

    /**
     * Parses the next {@code MathTransform} in the specified <cite>Well Know Text</cite> (WKT) tree.
     *
     * @param  element    the parent element.
     * @param  mandatory  {@code true} if a math transform must be present, or {@code false} if optional.
     * @return the next element as a {@code MathTransform} object, or {@code null}.
     * @throws ParseException if the next element can not be parsed.
     */
    final MathTransform parseMathTransform(final Element element, final boolean mandatory) throws ParseException {
        lastMethod = null;
        classification = null;
        MathTransform tr;
        if ((tr = parseParamMT       (element)) == null &&
            (tr = parseConcatMT      (element)) == null &&
            (tr = parseInverseMT     (element)) == null &&
            (tr = parsePassThroughMT (element)) == null)
        {
            if (mandatory) {
                throw element.missingOrUnknownComponent(WKTKeywords.Param_MT);
            }
        }
        return tr;
    }

    /**
     * Parses the {@code ID["authority", "code"]} element inside a {@code UNIT} element.
     * If such element is found, the authority is {@code "EPSG"} and the code is one of
     * the codes known to the {@link Units#valueOfEPSG(int)}, then that unit is returned.
     * Otherwise this method returns null.
     *
     * <div class="note"><b>Note:</b>
     * this method is a slight departure of ISO 19162, which said <cite>"Should any attributes or values given
     * in the cited identifier be in conflict with attributes or values given explicitly in the WKT description,
     * the WKT values shall prevail."</cite> But some units can hardly be expressed by the {@code UNIT} element,
     * because the later can contain only a conversion factor. For example sexagesimal units (EPSG:9108, 9110
     * and 9111) can hardly be expressed in an other way than by their EPSG code. Thankfully, identifiers in
     * {@code UNIT} elements are rare, so risk of conflicts should be low.</div>
     *
     * @param  parent  the parent {@code "UNIT"} element.
     * @return the unit from the identifier code, or {@code null} if none.
     * @throws ParseException if the {@code "ID"} can not be parsed.
     */
    final Unit<?> parseUnitID(final Element parent) throws ParseException {
        final Element element = parent.pullElement(OPTIONAL, ID_KEYWORDS);
        if (element != null) {
            final String codeSpace = element.pullString("codeSpace");
            final Object code      = element.pullObject("code");            // Accepts Integer as well as String.
            element.close(ignoredElements);
            if (Constants.EPSG.equalsIgnoreCase(codeSpace)) try {
                final int n;
                if (Numbers.isInteger(code.getClass())) {
                    n = ((Number) code).intValue();
                } else {
                    n = Integer.parseInt(code.toString());
                }
                return Units.valueOfEPSG(n);
            } catch (NumberFormatException e) {
                warning(parent, element, null, e);
            }
        }
        return null;
    }

    /**
     * Parses an optional {@code "UNIT"} element of unknown dimension.
     * This method tries to infer the quantity dimension from the unit keyword.
     *
     * @param  parent  the parent element.
     * @return the {@code "UNIT"} element, or {@code null} if none.
     * @throws ParseException if the {@code "UNIT"} can not be parsed.
     *
     * @see GeodeticObjectParser#parseScaledUnit(Element, String, Unit)
     */
    final Unit<?> parseUnit(final Element parent) throws ParseException {
        final Element element = parent.pullElement(OPTIONAL, UNIT_KEYWORDS);
        if (element == null) {
            return null;
        }
        final String  name   = element.pullString("name");
        double        factor = element.pullDouble("factor");
        final int     index  = element.getKeywordIndex() - 1;
        final Unit<?> unit   = parseUnitID(element);
        element.close(ignoredElements);
        if (unit != null) {
            return unit;
        }
        /*
         * Conversion factor can be applied only if the base dimension (angle, linear, scale, etc.) is known.
         * However before to apply that factor, we may need to fix rounding errors found in some WKT strings.
         * In particular, the conversion factor for degrees is sometime written as 0.01745329252 instead of
         * 0.017453292519943295.
         */
        if (index >= 0 && index < BASE_UNITS.length) {
            if (index < CONVERSION_FACTORS.length) {
                factor = completeUnitFactor(CONVERSION_FACTORS[index], factor);
            }
            return BASE_UNITS[index].multiply(factor);
        }
        // If we can not infer the base type, we have to rely on the name.
        try {
            return parseUnit(name);
        } catch (ParserException e) {
            throw new UnparsableObjectException(errorLocale, Errors.Keys.UnknownUnit_1,
                    new Object[] {name}, element.offset).initCause(e);
        }
    }

    /**
     * If the unit conversion factor specified in the Well Known Text is missing some fraction digits,
     * tries to complete them. The main use case is to replace 0.01745329252 by 0.017453292519943295
     * in degree units.
     *
     * @param  predefined  some known conversion factors, in ascending order.
     * @param  factor      the conversion factor specified in the Well Known Text element.
     * @return the conversion factor to use.
     */
    private static double completeUnitFactor(final double[] predefined, final double factor) {
        int i = Arrays.binarySearch(predefined, factor);
        if (i < 0) {
            i = Math.max(~i, 1);
            double accurate = predefined[i-1];
            if (i < predefined.length) {
                double next = predefined[i];
                if (next - factor < factor - accurate) {
                    accurate = next;
                }
            }
            if (DecimalFunctions.equalsIgnoreMissingFractionDigits(accurate, factor)) {
                return accurate;
            }
        }
        return factor;
    }

    /**
     * If the unit conversion factor specified in the Well Known Text is missing some fraction digits,
     * tries to complete them. The main use case is to replace 0.01745329252 by 0.017453292519943295
     * in degree units.
     *
     * @param  baseUnit  the base unit for which to complete the conversion factor.
     * @param  factor    the conversion factor specified in the Well Known Text element.
     * @return the conversion factor to use.
     */
    static double completeUnitFactor(final Unit<?> baseUnit, final double factor) {
        for (int i=CONVERSION_FACTORS.length; --i>=0;) {
            if (BASE_UNITS[i] == baseUnit) {
                return completeUnitFactor(CONVERSION_FACTORS[i], factor);
            }
        }
        return factor;
    }

    /**
     * Parses a sequence of {@code "PARAMETER"} elements.
     *
     * @param  element             the parent element containing the parameters to parse.
     * @param  parameters          the group where to store the parameter values.
     * @param  defaultUnit         the default unit (for arbitrary quantity, including angular), or {@code null}.
     * @param  defaultAngularUnit  the default angular unit, or {@code null} if none. This is determined by the context,
     *                             especially when {@link GeodeticObjectParser} parses a {@code ProjectedCRS} element.
     * @throws ParseException if the {@code "PARAMETER"} element can not be parsed.
     */
    final void parseParameters(final Element element, final ParameterValueGroup parameters,
            final Unit<?> defaultUnit, final Unit<Angle> defaultAngularUnit) throws ParseException
    {
        final Unit<?> defaultSI = (defaultUnit != null) ? defaultUnit.getSystemUnit() : null;
        Element param = element;
        try {
            while ((param = element.pullElement(OPTIONAL, WKTKeywords.Parameter)) != null) {
                final String name = param.pullString("name");
                Unit<?> unit = parseUnit(param);
                param.pullElement(OPTIONAL, ID_KEYWORDS);
                /*
                 * DEPARTURE FROM ISO 19162: the specification recommends that we use the identifier instead
                 * than the parameter name. However we do not yet have a "get parameter by ID" in Apache SIS
                 * or in GeoAPI interfaces. This was not considered necessary since SIS is lenient (hopefully
                 * without introducing ambiguity) regarding parameter names, but we may revisit in a future
                 * version if it become no longer the case. See https://issues.apache.org/jira/browse/SIS-210
                 */
                final ParameterValue<?>      parameter  = parameters.parameter(name);
                final ParameterDescriptor<?> descriptor = parameter.getDescriptor();
                final Class<?>               valueClass = descriptor.getValueClass();
                final boolean                isNumeric  = Number.class.isAssignableFrom(valueClass);
                if (isNumeric && unit == null) {
                    unit = descriptor.getUnit();
                    if (unit != null) {
                        final Unit<?> si = unit.getSystemUnit();
                        if (si.equals(defaultSI)) {
                            unit = defaultUnit;
                        } else if (si.equals(Units.RADIAN)) {
                            unit = defaultAngularUnit;
                        }
                    }
                }
                if (unit != null) {
                    parameter.setValue(param.pullDouble("doubleValue"), unit);
                } else if (isNumeric) {
                    if (Numbers.isInteger(valueClass)) {
                        parameter.setValue(param.pullInteger("intValue"));
                    } else {
                        parameter.setValue(param.pullDouble("doubleValue"));
                    }
                } else if (valueClass == Boolean.class) {
                    parameter.setValue(param.pullBoolean("booleanValue"));
                } else {
                    parameter.setValue(param.pullString("stringValue"));
                }
                param.close(ignoredElements);
            }
        } catch (ParameterNotFoundException e) {
            throw new UnparsableObjectException(errorLocale, Errors.Keys.UnexpectedParameter_1,
                    new String[] {e.getParameterName()}, param.offset).initCause(e);
        } catch (InvalidParameterValueException e) {
            throw (ParseException) new ParseException(e.getLocalizedMessage(), param.offset).initCause(e);
        }
    }

    /**
     * Parses a {@code "PARAM_MT"} element. This element has the following pattern:
     *
     * {@preformat text
     *     PARAM_MT["<classification-name>" {,<parameter>}* ]
     * }
     *
     * @param  parent  the parent element.
     * @return the {@code "PARAM_MT"} element as an {@link MathTransform} object.
     * @throws ParseException if the {@code "PARAM_MT"} element can not be parsed.
     */
    private MathTransform parseParamMT(final Element parent) throws ParseException {
        final Element element = parent.pullElement(FIRST, WKTKeywords.Param_MT);
        if (element == null) {
            return null;
        }
        classification = element.pullString("classification");
        final MathTransformFactory mtFactory = factories.getMathTransformFactory();
        final ParameterValueGroup parameters;
        try {
            parameters = mtFactory.getDefaultParameters(classification);
        } catch (NoSuchIdentifierException exception) {
            throw element.parseFailed(exception);
        }
        /*
         * Scan over all PARAMETER["name", value] elements and
         * set the corresponding parameter in the parameter group.
         */
        parseParameters(element, parameters, null, null);
        element.close(ignoredElements);
        /*
         * We now have all information for constructing the math transform.
         */
        final MathTransform transform;
        try {
            transform = mtFactory.createParameterizedTransform(parameters);
        } catch (FactoryException exception) {
            throw element.parseFailed(exception);
        }
        lastMethod = mtFactory.getLastMethodUsed();
        return transform;
    }

    /**
     * Parses an {@code "INVERSE_MT"} element. This element has the following pattern:
     *
     * {@preformat text
     *     INVERSE_MT[<math transform>]
     * }
     *
     * @param  parent  the parent element.
     * @return the {@code "INVERSE_MT"} element as an {@link MathTransform} object.
     * @throws ParseException if the {@code "INVERSE_MT"} element can not be parsed.
     */
    private MathTransform parseInverseMT(final Element parent) throws ParseException {
        final Element element = parent.pullElement(FIRST, WKTKeywords.Inverse_MT);
        if (element == null) {
            return null;
        }
        MathTransform transform = parseMathTransform(element, true);
        try {
            transform = transform.inverse();
        } catch (NoninvertibleTransformException exception) {
            throw element.parseFailed(exception);
        }
        element.close(ignoredElements);
        return transform;
    }

    /**
     * Parses a {@code "PASSTHROUGH_MT"} element. This element has the following pattern:
     *
     * {@preformat text
     *     PASSTHROUGH_MT[<integer>, <math transform>]
     * }
     *
     * @param  parent  the parent element.
     * @return the {@code "PASSTHROUGH_MT"} element as an {@link MathTransform} object.
     * @throws ParseException if the {@code "PASSTHROUGH_MT"} element can not be parsed.
     */
    private MathTransform parsePassThroughMT(final Element parent) throws ParseException {
        final Element element = parent.pullElement(FIRST, WKTKeywords.PassThrough_MT);
        if (element == null) {
            return null;
        }
        final int firstAffectedCoordinate = parent.pullInteger("firstAffectedCoordinate");
        final MathTransform transform = parseMathTransform(element, true);
        final MathTransformFactory mtFactory = factories.getMathTransformFactory();
        element.close(ignoredElements);
        try {
            return mtFactory.createPassThroughTransform(firstAffectedCoordinate, transform, 0);
        } catch (FactoryException exception) {
            throw element.parseFailed(exception);
        }
    }

    /**
     * Parses a {@code "CONCAT_MT"} element. This element has the following pattern:
     *
     * {@preformat text
     *     CONCAT_MT[<math transform> {,<math transform>}*]
     * }
     *
     * @param  parent  the parent element.
     * @return the {@code "CONCAT_MT"} element as an {@link MathTransform} object.
     * @throws ParseException if the {@code "CONCAT_MT"} element can not be parsed.
     */
    private MathTransform parseConcatMT(final Element parent) throws ParseException {
        final Element element = parent.pullElement(FIRST, WKTKeywords.Concat_MT);
        if (element == null) {
            return null;
        }
        MathTransform transform = parseMathTransform(element, true);
        MathTransform optionalTransform;
        final MathTransformFactory mtFactory = factories.getMathTransformFactory();
        while ((optionalTransform = parseMathTransform(element, false)) != null) {
            try {
                transform = mtFactory.createConcatenatedTransform(transform, optionalTransform);
            } catch (FactoryException exception) {
                throw element.parseFailed(exception);
            }
        }
        element.close(ignoredElements);
        return transform;
    }

    /**
     * Returns the operation method for the last math transform parsed. This is used by
     * {@link GeodeticObjectParser} in order to built {@link org.opengis.referencing.crs.DerivedCRS}.
     */
    final OperationMethod getOperationMethod() {
        if (lastMethod == null) {
            /*
             * Safety in case some MathTransformFactory implementations do not support
             * getLastMethod(). Performs a slower and less robust check as a fallback.
             */
            if (classification != null) {
                final MathTransformFactory mtFactory = factories.getMathTransformFactory();
                lastMethod = CoordinateOperations.getOperationMethod(
                        mtFactory.getAvailableMethods(SingleOperation.class), classification);
            }
        }
        return lastMethod;
    }
}
