/*
 * 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.HashMap;
import java.io.Serializable;
import java.io.ObjectStreamException;
import org.opengis.referencing.cs.PolarCS;
import org.opengis.referencing.cs.SphericalCS;
import org.opengis.referencing.cs.EllipsoidalCS;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.cs.AxisDirection;
import org.apache.sis.internal.metadata.AxisNames;
import org.apache.sis.internal.referencing.AxisDirections;
import org.apache.sis.internal.referencing.WKTKeywords;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.Characters;


/**
 * Controls the replacement of characters, abbreviations and names between the objects in memory and their
 * WKT representations. The mapping is not necessarily one-to-one, for example the replacement of a Unicode
 * character by an ASCII character may not be reversible. The mapping may also depend on the element to transliterate,
 * for example some Greek letters like φ, λ and θ are mapped differently when they are used as mathematical symbols in
 * axis abbreviations rather than texts. Some mappings may also apply to words instead than characters, when the word
 * come from a controlled vocabulary.
 *
 * <div class="section">Permitted characters in Well Known Text</div>
 * The ISO 19162 standard restricts <cite>Well Known Text</cite> to the following characters in all
 * {@linkplain Formatter#append(String, ElementKind) quoted texts} except in {@code REMARKS["…"]} elements:
 *
 * <blockquote><pre>{@literal A-Z a-z 0-9 _ [ ] ( ) { } < = > . , : ; + - (space) % & ' " * ^ / \ ? | °}</pre></blockquote>
 *
 * They are ASCII codes 32 to 125 inclusive except ! (33), # (35), $ (36), @ (64) and ` (96),
 * plus the addition of ° (176) despite being formally outside the ASCII character set.
 * The only exception to this rules is for the text inside {@code REMARKS["…"]} elements,
 * where all Unicode characters are allowed.
 *
 * <p>The {@link #filter(String)} method is responsible for replacing or removing characters outside the above-cited
 * set of permitted characters.</p>
 *
 * <div class="section">Application to mathematical symbols</div>
 * For Greek letters used as mathematical symbols in
 * {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#getAbbreviation() coordinate axis abbreviations},
 * the ISO 19162 standard recommends:
 *
 * <ul>
 *   <li>(<var>P</var>, <var>L</var>) as the transliteration of the Greek letters (<var>phi</var>, <var>lambda</var>), or
 *       (<var>B</var>, <var>L</var>) from German “Breite” and “Länge” used in academic texts worldwide, or
 *       (<var>lat</var>, <var>long</var>).</li>
 *   <li>(<var>U</var>) for (θ) in {@linkplain org.apache.sis.referencing.cs.DefaultPolarCS polar coordinate systems}.</li>
 *   <li>(<var>U</var>, <var>V</var>) for (Ω, θ) in
 *       {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS spherical coordinate systems}.</li>
 * </ul>
 *
 * <div class="note"><b>Note:</b> at least two conventions exist about the meaning of (<var>r</var>, θ, φ) in a
 * spherical coordinate system (see <a href="http://en.wikipedia.org/wiki/Spherical_coordinate_system">Wikipedia</a>
 * or <a href="http://mathworld.wolfram.com/SphericalCoordinates.html">MathWorld</a> for more information).
 * When using the <em>mathematics</em> convention, θ is the azimuthal angle in the
 * equatorial plane (roughly equivalent to longitude λ) while φ is an angle measured from a pole (also known as
 * colatitude). But when using the <em>physics</em> convention, the meaning of θ and φ are interchanged.
 * Furthermore some other conventions may measure the φ angle from the equatorial plane – like latitude – instead
 * than from the pole. This class does not need to care about the meaning of those angles. The only recommendation
 * is that φ is mapped to <var>U</var> and θ is mapped to <var>V</var>, regardless of their meaning.</div>
 *
 * The {@link #toLatinAbbreviation toLatinAbbreviation(…)} and {@link #toUnicodeAbbreviation toUnicodeAbbreviation(…)}
 * methods are responsible for doing the transliteration at formatting and parsing time, respectively.
 *
 * <div class="section">Replacement of names</div>
 * The longitude and latitude axis names are explicitly fixed by ISO 19111:2007 to <cite>"Geodetic longitude"</cite>
 * and <cite>"Geodetic latitude"</cite>. But ISO 19162:2015 §7.5.3(ii) said that the <cite>"Geodetic"</cite> part in
 * those names shall be omitted at WKT formatting time.
 * The {@link #toShortAxisName toShortAxisName(…)} and {@link #toLongAxisName toLongAxisName(…)}
 * methods are responsible for doing the transliteration at formatting and parsing time, respectively.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 *
 * @see org.apache.sis.util.Characters#isValidWKT(int)
 * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#39">WKT 2 specification §7.5.3</a>
 *
 * @since 0.6
 * @module
 */
public abstract class Transliterator implements Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = 7115456393795045932L;

    /**
     * A bitmask of control characters that are considered as spaces according {@link Character#isWhitespace(char)}.
     */
    static final int SPACES = 0xF0003E00;

    /**
     * Default names to associate to axis directions in a Cartesian coordinate system.
     * Those names do not apply to other kind of coordinate systems.
     *
     * <p>For thread safety reasons, this map shall not be modified after construction.</p>
     */
    private static final Map<AxisDirection,String> CARTESIAN;
    static {
        final Map<AxisDirection,String> m = new HashMap<>(12);
        m.put(AxisDirection.EAST,         AxisNames.EASTING);
        m.put(AxisDirection.WEST,         AxisNames.WESTING);
        m.put(AxisDirection.NORTH,        AxisNames.NORTHING);
        m.put(AxisDirection.SOUTH,        AxisNames.SOUTHING);
        m.put(AxisDirection.GEOCENTRIC_X, AxisNames.GEOCENTRIC_X);
        m.put(AxisDirection.GEOCENTRIC_Y, AxisNames.GEOCENTRIC_Y);
        m.put(AxisDirection.GEOCENTRIC_Z, AxisNames.GEOCENTRIC_Z);
        CARTESIAN = m;
    }

    /**
     * A transliterator compliant with ISO 19162 on a <cite>"best effort"</cite> basis.
     * All methods perform the default implementation documented in this {@code Transliterator} class.
     */
    public static final Transliterator DEFAULT = new Default();

    /**
     * A transliterator that does not perform any replacement.
     * All methods let names, abbreviations and Unicode characters pass-through unchanged.
     */
    public static final Transliterator IDENTITY = new Unicode();

    /**
     * For sub-class constructors.
     */
    protected Transliterator() {
    }

    /**
     * Returns a character sequences with the non-ASCII characters replaced or removed.
     * For example this method replaces “ç” by “c” in “Triangulation fran<b>ç</b>aise”.
     * This operation is usually not reversible; there is no converse method.
     *
     * <p>Implementations shall not care about {@linkplain Symbols#getOpeningQuote(int) opening} or
     * {@linkplain Symbols#getClosingQuote(int) closing quotes}. The quotes will be doubled by the
     * caller if needed after this method has been invoked.</p>
     *
     * <p>The default implementation invokes {@link CharSequences#toASCII(CharSequence)},
     * replaces line feed and tabulations by single spaces, then remove control characters.</p>
     *
     * @param  text  the text to format without non-ASCII characters.
     * @return the text to write in <cite>Well Known Text</cite>.
     *
     * @see org.apache.sis.util.Characters#isValidWKT(int)
     */
    public String filter(final String text) {
        CharSequence s = CharSequences.toASCII(text);
        StringBuilder buffer = null;
        for (int i=s.length(); --i >= 0;) {
            final char c = s.charAt(i);
            if (c < 32) {
                if (buffer == null) {
                    if (s == text) {
                        s = buffer = new StringBuilder(text);
                    } else {
                        buffer = (StringBuilder) s;
                    }
                }
                if ((SPACES & (1 << c)) != 0) {
                    buffer.setCharAt(i, ' ');
                    if (i != 0 && c == '\n' && s.charAt(i-1) == '\r') {
                        buffer.deleteCharAt(--i);
                    }
                } else {
                    buffer.deleteCharAt(i);
                }
            }
        }
        return s.toString();
    }

    /**
     * Returns the axis name to format in WKT, or {@code null} if none. This method performs the mapping
     * between the names of axes in memory (designated by <cite>"long axis names"</cite> in this class)
     * and the names to format in the WKT (designated by <cite>"short axis names"</cite>).
     *
     * <div class="note"><b>Note:</b>
     * the <cite>"long axis names"</cite> are defined by ISO 19111 — <cite>referencing by coordinates</cite>
     * while the <cite>"short axis names"</cite> are defined by ISO 19162 — <cite>Well-known text representation
     * of coordinate reference systems</cite>.</div>
     *
     * This method can return {@code null} if the name should be omitted.
     * ISO 19162 recommends to omit the axis name when it is already given through the mandatory axis direction.
     *
     * <p>The default implementation performs at least the following replacements:</p>
     * <ul>
     *   <li>Replace <cite>“Geodetic latitude”</cite> (case insensitive) by <cite>“Latitude”</cite>.</li>
     *   <li>Replace <cite>“Geodetic longitude”</cite> (case insensitive) by <cite>“Longitude”</cite>.</li>
     *   <li>Return {@code null} if the axis direction is {@link AxisDirection#GEOCENTRIC_X}, {@code GEOCENTRIC_Y}
     *       or {@code GEOCENTRIC_Z} and the name is the same than the axis direction (ignoring case).</li>
     * </ul>
     *
     * @param  cs         the enclosing coordinate system, or {@code null} if unknown.
     * @param  direction  the direction of the axis to format.
     * @param  name       the axis name, to be eventually replaced by this method.
     * @return the axis name to format, or {@code null} if the name shall be omitted.
     *
     * @see org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#formatTo(Formatter)
     */
    public String toShortAxisName(final CoordinateSystem cs, final AxisDirection direction, final String name) {
        if (name.equalsIgnoreCase(AxisNames.GEODETIC_LATITUDE )) return AxisNames.LATITUDE;  // ISO 19162:2015 §7.5.3(ii)
        if (name.equalsIgnoreCase(AxisNames.GEODETIC_LONGITUDE)) return AxisNames.LONGITUDE;
        if (AxisDirections.isGeocentric(direction) && CharSequences.equalsFiltered(
                name, direction.name(), Characters.Filter.LETTERS_AND_DIGITS, true))
        {
            return null;
        }
        return name;
    }

    /**
     * Returns the axis name to use in memory for an axis parsed from a WKT.
     * Since this method is invoked before the {@code CoordinateSystem} instance is created,
     * most coordinate system characteristics are known only as {@code String}.
     * In particular the {@code csType} argument, if non-null, should be one of the following values:
     *
     * <blockquote>{@code "affine"}, {@code "Cartesian"} (note the upper-case {@code "C"}), {@code "cylindrical"},
     * {@code "ellipsoidal"}, {@code "linear"}, {@code "parametric"}, {@code "polar"}, {@code "spherical"},
     * {@code "temporal"} or {@code "vertical"}</blockquote>
     *
     * This method is the converse of {@link #toShortAxisName(CoordinateSystem, AxisDirection, String)}.
     * The default implementation performs at least the following replacements:
     * <ul>
     *   <li>Replace <cite>“Lat”</cite> or <cite>“Latitude”</cite>
     *       (case insensitive) by <cite>“Geodetic latitude”</cite> or <cite>“Spherical latitude”</cite>,
     *       depending on whether the axis is part of an ellipsoidal or spherical CS respectively.</li>
     *   <li>Replace <cite>“Lon”</cite>, <cite>“Long”</cite> or <cite>“Longitude”</cite>
     *       (case insensitive) by <cite>“Geodetic longitude”</cite> or <cite>“Spherical longitude”</cite>,
     *       depending on whether the axis is part of an ellipsoidal or spherical CS respectively.</li>
     *   <li>Return <cite>“Geocentric X”</cite>, <cite>“Geocentric Y”</cite> and <cite>“Geocentric Z”</cite>
     *       for {@link AxisDirection#GEOCENTRIC_X}, {@link AxisDirection#GEOCENTRIC_Y GEOCENTRIC_Y}
     *       and {@link AxisDirection#GEOCENTRIC_Z GEOCENTRIC_Z} respectively in a Cartesian CS,
     *       if the given axis name is only an abbreviation.</li>
     *   <li>Use unique camel-case names for axis names defined by ISO 19111 and ISO 19162. For example this method
     *       replaces <cite>“<b>e</b>llipsoidal height”</cite> by <cite>“<b>E</b>llipsoidal height”</cite>.</li>
     * </ul>
     *
     * <div class="note"><b>Rational:</b>
     * Axis names are not really free text. They are specified by ISO 19111 and ISO 19162.
     * SIS does not put restriction on axis names, but we nevertheless try to use a unique
     * name when we recognize it.</div>
     *
     * @param  csType     the type of the coordinate system, or {@code null} if unknown.
     * @param  direction  the parsed axis direction.
     * @param  name       the parsed axis abbreviation, to be eventually replaced by this method.
     * @return the axis name to use. Can not be null.
     */
    public String toLongAxisName(final String csType, final AxisDirection direction, final String name) {
        if (csType != null) switch (csType) {
            case WKTKeywords.ellipsoidal: {
                if (isLatLong(AxisNames.LATITUDE,  name)) return AxisNames.GEODETIC_LATITUDE;
                if (isLatLong(AxisNames.LONGITUDE, name)) return AxisNames.GEODETIC_LONGITUDE;
                break;
            }
            case WKTKeywords.spherical: {
                if (isLatLong(AxisNames.LATITUDE,  name)) return AxisNames.SPHERICAL_LATITUDE;
                if (isLatLong(AxisNames.LONGITUDE, name)) return AxisNames.SPHERICAL_LONGITUDE;
                break;
            }
            case WKTKeywords.Cartesian: {
                if (name.length() <= 1) {
                    final String c = CARTESIAN.get(direction);
                    if (c != null) {
                        return c;
                    }
                }
                break;
            }
        }
        return AxisNames.toCamelCase(name);
    }

    /**
     * Returns {@code true} if the given axis name is at least part of the given expected axis name.
     *
     * @param  expected  {@link AxisNames#LATITUDE} or {@link AxisNames#LONGITUDE}.
     * @param  name      the parsed axis name.
     */
    private static boolean isLatLong(final String expected, final String name) {
        final int length = name.length();
        return (length >= 3) && (length <= name.length()) && CharSequences.startsWith(expected, name, true);
    }

    /**
     * Returns the axis abbreviation to format in WKT, or {@code null} if none. The given abbreviation may contain
     * Greek letters, in particular φ, λ and θ. This {@code toLatinAbbreviation(…)} method is responsible
     * for replacing Greek letters by Latin letters for ISO 19162 compliance, if desired.
     *
     * <p>The default implementation performs at least the following mapping:</p>
     * <ul>
     *   <li>λ → <var>L</var> (from German <cite>Länge</cite>) if used in an
     *       {@linkplain org.apache.sis.referencing.cs.DefaultEllipsoidalCS ellipsoidal CS}.</li>
     *   <li>φ → <var>B</var> (from German <cite>Breite</cite>) if used in an
     *       {@linkplain org.apache.sis.referencing.cs.DefaultEllipsoidalCS ellipsoidal CS}.</li>
     *   <li>φ or φ′ or φ<sub>c</sub> or Ω → <var>U</var> if used in a
     *       {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS spherical CS}, regardless of whether the
     *       coordinate system follows <a href="http://en.wikipedia.org/wiki/Spherical_coordinate_system">physics,
     *       mathematics or other conventions</a>.</li>
     *   <li>θ → <var>V</var> if used in a {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS spherical CS} (regardless of above-cited coordinate system convention).</li>
     *   <li>θ → <var>U</var> if used in a polar CS.</li>
     * </ul>
     *
     * Note that while this method may return a string of any length, ISO 19162 requires abbreviations
     * to be a single Latin character.
     *
     * @param  cs            the enclosing coordinate system, or {@code null} if unknown.
     * @param  direction     the direction of the axis to format.
     * @param  abbreviation  the axis abbreviation, to be eventually replaced by this method.
     * @return the axis abbreviation to format.
     *
     * @see org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#formatTo(Formatter)
     */
    public String toLatinAbbreviation(final CoordinateSystem cs, final AxisDirection direction, String abbreviation) {
        if (abbreviation != null && !abbreviation.isEmpty()) {
            if (abbreviation.length() <= 2) {
                switch (abbreviation.charAt(0)) {
                    /*
                     * ISO 19162:2015 §7.5.3 recommendations:
                     *
                     *   a) For PolarCS using Greek letter θ for direction, the letter ‘U’ should be used in WKT.
                     *   b) For SphericalCS using φ and θ, the letter ‘U’ and ‘V’ respectively should be used in WKT.
                     */
                    case 'θ': {
                        if  (cs instanceof SphericalCS) abbreviation ="V";
                        else if (cs instanceof PolarCS) abbreviation ="U";
                        break;
                    }
                    /*
                     * ISO 19162:2015 §7.5.3 requirement (ii) and recommendation (b):
                     *
                     *  ii) Greek letters φ and λ for geodetic latitude and longitude must be replaced by Latin char.
                     *   b) For SphericalCS using φ and θ, the letter ‘U’ and ‘V’ respectively should be used in WKT.
                     *
                     * Note that some SphericalCS may use φ′ or φc for distinguishing from geodetic latitude φ.
                     */
                    case 'φ': {
                        if (cs instanceof SphericalCS) {
                            abbreviation = "U";
                        } else if (cs instanceof EllipsoidalCS) {
                            abbreviation = "B";    // From German "Breite", used in academic texts worldwide.
                        }
                        break;
                    }
                    case 'Ω': {                    // Used instead of 'φ' in ISO 19111.
                        if (cs instanceof SphericalCS) {
                            abbreviation = "U";
                        }
                        break;
                    }
                    case 'λ': {
                        if (cs instanceof EllipsoidalCS) {
                            abbreviation = "L";    // From German "Länge", used in academic texts worldwide.
                        }
                        break;
                    }
                }
            } else {
                if (abbreviation.equalsIgnoreCase("Lat")) {
                    abbreviation = "B";
                } else if (abbreviation.regionMatches(true, 0, "Long", 0,
                        Math.min(3, Math.max(4, abbreviation.length()))))   // Accept "Lon" or "Long".
                {
                    abbreviation = "L";
                }
            }
        }
        return abbreviation;
    }

    /**
     * Returns the axis abbreviation to use in memory for an axis parsed from a WKT.
     * Since this method is invoked before the {@code CoordinateSystem} instance is created,
     * most coordinate system characteristics are known only as {@code String}.
     * In particular the {@code csType} argument, if non-null, should be one of the following values:
     *
     * <blockquote>{@code "affine"}, {@code "Cartesian"} (note the upper-case {@code "C"}), {@code "cylindrical"},
     * {@code "ellipsoidal"}, {@code "linear"}, {@code "parametric"}, {@code "polar"}, {@code "spherical"},
     * {@code "temporal"} or {@code "vertical"}</blockquote>
     *
     * This method is the converse of {@link #toLatinAbbreviation(CoordinateSystem, AxisDirection, String)}.
     * The default implementation performs at least the following mapping:
     * <ul>
     *   <li><var>P</var> or <var>L</var> → λ if {@code csType} is {@code "ellipsoidal"}.</li>
     *   <li><var>B</var> → φ  if {@code csType} is {@code "ellipsoidal"}.</li>
     *   <li><var>U</var> → Ω  if {@code csType} is {@code "spherical"}, regardless of coordinate system convention.</li>
     *   <li><var>V</var> → θ  if {@code csType} is {@code "spherical"}, regardless of coordinate system convention.</li>
     *   <li><var>U</var> → θ  if {@code csType} is {@code "polar"}.</li>
     * </ul>
     *
     * @param  csType        the type of the coordinate system, or {@code null} if unknown.
     * @param  direction     the parsed axis direction.
     * @param  abbreviation  the parsed axis abbreviation, to be eventually replaced by this method.
     * @return the axis abbreviation to use. Can not be null.
     */
    public String toUnicodeAbbreviation(final String csType, final AxisDirection direction, String abbreviation) {
        if (abbreviation.length() == 1) {
            final String replacement;
            final String condition;
            switch (abbreviation.charAt(0)) {
                case 'U': if (WKTKeywords.polar.equals(csType)) return "θ";
                          replacement = "Ω";  condition = WKTKeywords.spherical;   break;
                case 'V': replacement = "θ";  condition = WKTKeywords.spherical;   break;
                case 'L': replacement = "λ";  condition = WKTKeywords.ellipsoidal; break;
                case 'P': // Transliteration of "phi".
                case 'B': replacement = "φ";  condition = WKTKeywords.ellipsoidal; break;
                default: return abbreviation;
            }
            if (condition.equals(csType)) {
                return replacement;
            }
        } else {
            if (isLatLong(AxisNames.LATITUDE,  abbreviation)) return "φ";
            if (isLatLong(AxisNames.LONGITUDE, abbreviation)) return "λ";
        }
        return abbreviation;
    }

    /**
     * The {@link Transliterator#DEFAULT} implementation.
     */
    private static final class Default extends Transliterator {
        /** For cross-version compatibility. */
        private static final long serialVersionUID = 4869597020294928525L;

        /** Returns a string representation similar to enum. */
        @Override public String toString() {
            return "DEFAULT";
        }

        /** Replaces deserialized instances by the unique instance. */
        Object readResolve() throws ObjectStreamException {
            return DEFAULT;
        }
    }

    /**
     * The {@link Transliterator#IDENTITY} implementation.
     */
    private static final class Unicode extends Transliterator {
        /** For cross-version compatibility. */
        private static final long serialVersionUID = 7392131912748253956L;

        /** Performs no replacement. */
        @Override public String filter(String text) {
            return text;
        }

        /** Returns the axis name as-is. */
        @Override public String toShortAxisName(CoordinateSystem cs, AxisDirection direction, String name) {
            return name;
        }

        /** Returns the axis name as-is. */
        @Override public String toLongAxisName(String csType, AxisDirection direction, String name) {
            return name;
        }

        /** Returns the abbreviation as-is. */
        @Override public String toLatinAbbreviation(CoordinateSystem cs, AxisDirection direction, String abbreviation) {
            return abbreviation;
        }

        /** Returns the abbreviation as-is. */
        @Override
        public String toUnicodeAbbreviation(String csType, AxisDirection direction, String abbreviation) {
            return abbreviation;
        }

        /** Returns a string representation similar to enum. */
        @Override public String toString() {
            return "IDENTITY";
        }

        /** Replaces deserialized instances by the unique instance. */
        Object readResolve() throws ObjectStreamException {
            return IDENTITY;
        }
    }
}
