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

import java.util.Locale;
import java.util.Collection;
import javax.measure.Unit;
import org.opengis.util.GenericName;
import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.cs.AxisDirection;
import org.apache.sis.util.Characters;
import org.apache.sis.util.CharSequences;
import org.apache.sis.measure.Units;

// Specific to the geoapi-3.1 and geoapi-4.0 branches:
import org.opengis.referencing.datum.RealizationMethod;


/**
 * Extensions to the standard set of {@link RealizationEpoch}.
 * Some of those constants are derived from a legacy {@code VerticalDatumType} code list.
 * Those constants are not in public API because they were intentionally omitted from ISO 19111,
 * and the ISO experts said that they should really not be public.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 */
public final class VerticalDatumTypes {
    /**
     * A pseudo-realization method for ellipsoidal heights that are measured along
     * the normal to the ellipsoid used in the definition of horizontal datum.
     * <strong>The use of this method is deprecated</strong> as ellipsoidal height
     * should never be separated from the horizontal components according ISO 19111.
     *
     * <h4>Legacy</h4>
     * This type was associated to code 2000 in the {@code Vert_Datum} element of the legacy WKT 1 format.
     * The UML identifier was {@code CS_DatumType.CS_VD_Ellipsoidal}.
     *
     * @see org.apache.sis.referencing.CommonCRS.Vertical#ELLIPSOIDAL
     */
    static final String ELLIPSOIDAL = "ELLIPSOIDAL";

    /**
     * A vertical datum type for orthometric heights that are measured along the plumb line.
     *
     * <h4>Legacy</h4>
     * This type was associated to code 2001 in the {@code Vert_Datum} element of the legacy WKT 1 format.
     * The UML identifier was {@code CS_DatumType.CS_VD_Orthometric}.
     */
    private static final String ORTHOMETRIC = "ORTHOMETRIC";

    /**
     * A vertical datum type for origin of the vertical axis based on atmospheric pressure.
     *
     * <h4>Legacy</h4>
     * This type was associated to code 2003 in the {@code Vert_Datum} element of the legacy WKT 1 format.
     * The UML identifier was {@code CS_DatumType.CS_VD_AltitudeBarometric}.
     *
     * @see org.apache.sis.referencing.CommonCRS.Vertical#BAROMETRIC
     */
    static final String BAROMETRIC = "BAROMETRIC";

    /**
     * Do not allow instantiation of this class.
     */
    private VerticalDatumTypes() {
    }

    /**
     * Returns a pseudo-realization method for ellipsoidal heights.
     * <strong>The use of this method is deprecated</strong> as ellipsoidal height
     * should never be separated from the horizontal components according ISO 19111.
     *
     * <h4>Maintenance note</h4>
     * If the implementation of this method is modified, search for {@code RealizationMethod.valueOf}
     * at least in {@link org.apache.sis.referencing.CommonCRS.Vertical#datum()} and make sure that
     * the code is equivalent.
     *
     * @return the ellipsoidal pseudo-realization method.
     */
    public static RealizationMethod ellipsoidal() {
        return RealizationMethod.valueOf(ELLIPSOIDAL);
    }

    /**
     * Returns {@code true} if the given value is the ellipsoidal pseudo-realization method.
     *
     * @param  method  the method to test, or {@code null}.
     * @return whether the given method is the ellipsoidal pseudo-realization method.
     */
    public static boolean ellipsoidal(final RealizationMethod method) {
        return (method != null) && ELLIPSOIDAL.equalsIgnoreCase(method.name());
    }

    /**
     * Returns the vertical datum type from a legacy code. The legacy codes were defined in
     * OGC 01-009 (<cite>Coordinate Transformation Services)</cite>, which also defined the version 1
     * of <cite>Well Known Text</cite></a> format (WKT 1). This method is used for WKT 1 parsing.
     *
     * @param  code  the legacy vertical datum code.
     * @return the vertical datum type, or {@code null} if none.
     */
    public static RealizationMethod fromLegacy(final int code) {
        switch (code) {
        //  case 2000: return null;                                     // CS_VD_Other
            case 2001: return RealizationMethod.valueOf(ORTHOMETRIC);   // CS_VD_Orthometric
            case 2002: return ellipsoidal();                            // CS_VD_Ellipsoidal
            case 2003: return RealizationMethod.valueOf(BAROMETRIC);    // CS_VD_AltitudeBarometric
            case 2005: return RealizationMethod.GEOID;                  // CS_VD_GeoidModelDerived
            case 2006: return RealizationMethod.TIDAL;                  // CS_VD_Depth
            default:   return null;
        }
    }

    /**
     * Returns the legacy code for the datum type, or 2000 (other surface) if unknown.
     * This method is used for WKT 1 formatting.
     *
     * @param  method  the realization method, or {@code null} if unknown.
     * @return the legacy code for the given datum type, or 0 if unknown.
     */
    public static int toLegacy(final RealizationMethod method) {
        if (method != null) {
            switch (method.name().toUpperCase(Locale.US)) {
                case ORTHOMETRIC: return 2001;      // CS_VD_Orthometric
                case ELLIPSOIDAL: return 2002;      // CS_VD_Ellipsoidal
                case BAROMETRIC:  return 2003;      // CS_VD_AltitudeBarometric
                case "GEOID":     return 2005;      // CS_VD_GeoidModelDerived
                case "TIDAL":     return 2006;      // CS_VD_Depth
            }
        }
        return 2000;
    }

    /**
     * Returns the vertical datum type from a realization method.
     * If the given method cannot be mapped to a legacy type, then this method returns "other surface".
     * This is because the vertical datum type was a mandatory property in legacy OGC/ISO standards.
     * This method is used for writing GML documents older than GML 3.2.
     *
     * @param  method  the realization method, or {@code null}.
     * @return the vertical datum type name (never null).
     */
    public static String toName(final RealizationMethod method) {
        if (method == RealizationMethod.GEOID) return "geoidal";
        if (method == RealizationMethod.TIDAL) return "depth";
        if (method != null) {
            return method.name().toLowerCase(Locale.US);
        }
        return "other surface";
    }

    /**
     * Returns the realization method from a vertical datum type.
     * This method is used for reading GML documents older than GML 3.2.
     *
     * @param  type  the vertical datum type, or {@code null}.
     * @return the realization method, or {@code null} if none.
     */
    public static RealizationMethod fromName(final String type) {
        if ("GEOIDAL"  .equalsIgnoreCase(type)) return RealizationMethod.GEOID;
        if ("DEPTH"    .equalsIgnoreCase(type)) return RealizationMethod.TIDAL;
        if (BAROMETRIC .equalsIgnoreCase(type)) return RealizationMethod.valueOf(BAROMETRIC);
        if (ORTHOMETRIC.equalsIgnoreCase(type)) return RealizationMethod.valueOf(ORTHOMETRIC);
        if (ELLIPSOIDAL.equalsIgnoreCase(type)) return ellipsoidal();
        return null;
    }

    /**
     * Guesses the realization method of a datum from its name, aliases or a given vertical axis.
     * This is sometimes needed after XML unmarshalling or WKT parsing, because GML 3.2 and ISO 19162
     * do not contain any attribute for the datum type.
     *
     * <p>This method uses heuristic rules and may be changed in any future SIS version.</p>
     *
     * @param  name     the name of the datum for which to guess a type, or {@code null} if unknown.
     * @param  aliases  the aliases of the datum for which to guess a type, or {@code null} if unknown.
     * @param  axis     the vertical axis for which to guess a type, or {@code null} if unknown.
     * @return a datum type, or {@code null} if none can be guessed.
     */
    public static RealizationMethod guess(final String name, final Collection<? extends GenericName> aliases,
            final CoordinateSystemAxis axis)
    {
        RealizationMethod method = guess(name);
        if (method != null) {
            return method;
        }
        if (aliases != null) {
            for (final GenericName alias : aliases) {
                method = guess(alias.tip().toString());
                if (method != null) {
                    return method;
                }
            }
        }
        if (axis != null) {
            final Unit<?> unit = axis.getUnit();
            if (Units.isLinear(unit)) {
                final String abbreviation = axis.getAbbreviation();
                if (abbreviation.length() == 1) {
                    AxisDirection dir = AxisDirection.UP;               // Expected direction for accepting the type.
                    switch (abbreviation.charAt(0)) {
                        case 'h': method = ellipsoidal(); break;
                        case 'H': method = RealizationMethod.GEOID; break;
                        case 'D': method = RealizationMethod.TIDAL; dir = AxisDirection.DOWN; break;
                        default:  return null;
                    }
                    if (dir.equals(axis.getDirection())) {
                        return method;
                    }
                }
            } else if (Units.isPressure(unit)) {
                return RealizationMethod.valueOf(BAROMETRIC);
            }
        }
        return null;
    }

    /**
     * Guesses the realization method of a datum of the given name. This method attempts to guess only if
     * the given name contains at least one letter. If the type cannot be determined, returns {@code null}.
     *
     * @param  name  name of the datum for which to guess a realization method, or {@code null}.
     * @return a realization method, or {@code null} if none can be guessed.
     */
    private static RealizationMethod guess(final String name) {
        if (name != null) {
            if (CharSequences.equalsFiltered("Mean Sea Level", name, Characters.Filter.LETTERS_AND_DIGITS, true)) {
                return RealizationMethod.TIDAL;
            }
            if (name.contains("geoid")) {
                return RealizationMethod.GEOID;
            }
        }
        return null;
    }
}
