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

import org.opengis.util.LocalName;
import org.opengis.util.ScopedName;
import org.opengis.util.GenericName;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.util.iso.Names;
import org.apache.sis.util.Static;

// Branch-dependent imports
import org.apache.sis.feature.AbstractFeature;
import org.apache.sis.feature.AbstractAttribute;
import org.apache.sis.feature.AbstractIdentifiedType;
import org.apache.sis.feature.AbstractOperation;
import org.apache.sis.feature.DefaultAttributeType;
import org.apache.sis.feature.DefaultFeatureType;


/**
 * Defines the names of some properties or characteristics for which we assign a conventional usage.
 * Properties with the names defined in this {@code AttributeConvention} class are often aliases generated
 * by the SIS implementation of various file readers. Those synthetic properties redirect to the most
 * appropriate "real" property in the feature.
 *
 * <div class="note"><b>Example:</b>
 * one of the most frequently used synthetic property is {@code "sis:identifier"}, which contains a unique
 * identifier (or primary key) for the feature. This property is usually (but not necessarily)
 * a {@linkplain org.apache.sis.feature.FeatureOperations#link link to an existing attribute}.
 * By using the {@code "sis:identifier"} alias, users do not need to know the name of the "real" attribute.
 * </div>
 *
 * This class defines names for two kinds of usage:
 * <ul>
 *   <li>Names ending with {@code "_PROPERTY"} are used for attributes or operations that are members of the
 *       collection returned by {@link org.apache.sis.feature.DefaultFeatureType#getProperties(boolean)}.</li>
 *   <li>Names ending with {@code "_CHARACTERISTIC"} are used for characteristics that are entries of the
 *       map returned by {@link org.apache.sis.feature.DefaultAttributeType#characteristics()}.</li>
 * </ul>
 *
 * <div class="section">Mixing with other conventions</div>
 * The conventions defined in this class are specific to Apache SIS.
 * Current implementation does not support any other convention than the SIS one,
 * but we may refactor this class in future SIS versions if there is a need to support different conventions.
 *
 * <p>In order to reduce the risk of name collision with properties in user-defined features
 * (e.g. the user may already have an attribute named {@code "identifier"} for his own purpose),
 * all names defined in this class begin with the {@code "@"} character.</p>
 *
 * @author  Johann Sorel (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.7
 * @module
 */
public final class AttributeConvention extends Static {
    /**
     * Scope of all names defined by SIS convention.
     */
    private static final LocalName SCOPE;

    /**
     * Conventional name for a property used as a unique identifier.
     * The identifier should be unique in the {@link org.apache.sis.storage.DataStore} instance containing the feature
     * (for example a {@code DataStore} opened for a XML file), but does not need to be unique between two independent
     * {@code DataStore} instances.
     *
     * <p>Properties of this name are usually
     * {@linkplain org.apache.sis.feature.FeatureOperations#link aliases for existing attributes}, or
     * {@linkplain org.apache.sis.feature.FeatureOperations#compound compound keys} made by concatenation
     * of two or more other attributes.</p>
     *
     * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} is usually
     * {@link String}, {@link Integer}, {@link java.util.UUID} or other types commonly used as identifiers.</p>
     */
    public static final ScopedName IDENTIFIER_PROPERTY;

    /**
     * Conventional name for a property containing the geometric object to use by default.
     * Some features may contain more than one geometric object; this property tells which
     * geometry to render on a map for example.
     *
     * <p>Properties of this name are usually {@linkplain org.apache.sis.feature.FeatureOperations#link
     * operations acting as a redirection to another attribute}.</p>
     *
     * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} can be
     * the {@link com.esri.core.geometry.Geometry} class from ESRI's API, or the {@code Geometry} class from
     * <cite>Java Topology Suite</cite> (JTS) library, or any other class defined in future SIS versions.
     * See {@code isGeometryAttribute(IdentifiedType)} for testing whether the value is a supported type.</p>
     *
     * @see #isGeometryAttribute(AbstractIdentifiedType)
     */
    public static final ScopedName GEOMETRY_PROPERTY;

    /**
     * Conventional name for fetching the envelope encompassing all geometries in a feature. Most {@code FeatureType}s
     * have at most one geometry, which is also the {@link #GEOMETRY_PROPERTY default geometry}.
     * But if several geometries exist, then the value for this synthetic property is the union of all geometries.
     *
     * <p>Properties of this name are usually
     * {@linkplain org.apache.sis.feature.FeatureOperations#envelope operations}.</p>
     *
     * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} should be
     * {@link org.opengis.geometry.Envelope}.</p>
     */
    public static final ScopedName ENVELOPE_PROPERTY;

    /**
     * Conventional name for fetching the Coordinate Reference System (CRS) of a geometry or a coverage.
     * This characteristic is typically an entry in the map returned by a call to the
     * {@link org.apache.sis.feature.DefaultAttributeType#characteristics()} method
     * on the attribute referenced by {@link #GEOMETRY_PROPERTY}.
     *
     * <p>While it is technically possible to have different CRS for different feature instances,
     * in most cases the CRS is the same for all geometries found in {@code GEOMETRY_PROPERTY}.
     * In such cases, the CRS can be specified only once as the
     * {@linkplain org.apache.sis.feature.DefaultAttributeType#getDefaultValue() default value}
     * of this {@code CRS_CHARACTERISTIC}.</p>
     *
     * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} should be
     * {@link org.opengis.referencing.crs.CoordinateReferenceSystem}.</p>
     *
     * @see #getCRSCharacteristic(Object)
     */
    public static final ScopedName CRS_CHARACTERISTIC;

    /**
     * Conventional name for fetching the maximal length of string values.
     * The maximal length is stored as the
     * {@linkplain org.apache.sis.feature.DefaultAttributeType#getDefaultValue() default value} of the
     * {@linkplain org.apache.sis.feature.DefaultAttributeType#characteristics() characteristic} associated
     * to the attribute on which the maximal length applies.
     *
     * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} should be
     * {@link Integer}.</p>
     *
     * @see #getMaximalLengthCharacteristic(Object)
     */
    public static final ScopedName MAXIMAL_LENGTH_CHARACTERISTIC;

    /**
     * Conventional name for fetching the enumeration of valid values.
     * The set of valid values is stored stored as the
     * {@linkplain org.apache.sis.feature.DefaultAttributeType#getDefaultValue() default value} of the
     * {@linkplain org.apache.sis.feature.DefaultAttributeType#characteristics() characteristic} associated
     * to the attribute on which the restriction applies.
     */
    public static final GenericName VALID_VALUES_CHARACTERISTIC;
    static {
        SCOPE                         = Names.createLocalName("Apache", null, "sis");
        IDENTIFIER_PROPERTY           = Names.createScopedName(SCOPE, null, "identifier");
        GEOMETRY_PROPERTY             = Names.createScopedName(SCOPE, null, "geometry");
        ENVELOPE_PROPERTY             = Names.createScopedName(SCOPE, null, "envelope");
        CRS_CHARACTERISTIC            = Names.createScopedName(SCOPE, null, "crs");
        MAXIMAL_LENGTH_CHARACTERISTIC = Names.createScopedName(SCOPE, null, "maximalLength");
        VALID_VALUES_CHARACTERISTIC   = Names.createScopedName(SCOPE, null, "validValues");
    }

    /**
     * String representation of the {@link #IDENTIFIER_PROPERTY} name.
     * This can be used in calls to {@link AbstractFeature#getPropertyValue(String)}.
     */
    public static final String IDENTIFIER = "sis:identifier";

    /**
     * String representation of the {@link #GEOMETRY_PROPERTY} name.
     * This can be used in calls to {@link AbstractFeature#getPropertyValue(String)}.
     */
    public static final String GEOMETRY = "sis:geometry";

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

    /**
     * Returns {@code true} if the given name stands for one of the synthetic properties defined by convention.
     * Conventional properties are properties added by the {@code DataStore} to the {@code FeatureType} in order
     * to provide a uniform way to access commonly used information.
     *
     * <p>Synthetic properties should generally not be written by the user.
     * Those properties are calculated most of the time and have only a meaning within SIS.</p>
     *
     * <p>Current implementation returns {@code true} if the given name is in the SIS namespace.</p>
     *
     * @param  name  the name of the property or characteristic to test, or {@code null}.
     * @return {@code true} if the given name is non-null and in the SIS namespace.
     */
    public static boolean contains(GenericName name) {
        while (name instanceof ScopedName) {
            if (SCOPE.equals(((ScopedName) name).path())) {
                return true;
            }
            name = ((ScopedName) name).tail();
        }
        return false;
    }

    /**
     * Returns {@code true} if the given feature type is non-null and has a {@value #IDENTIFIER} property.
     *
     * @param  feature  the feature type to test, or {@code null}.
     * @return whether the given feature type is non-null and has a {@value #IDENTIFIER} property.
     */
    public static boolean hasIdentifier(final DefaultFeatureType feature) {
        if (feature != null) try {
            return feature.getProperty(IDENTIFIER) != null;
        } catch (IllegalArgumentException e) {
            // Ignore
        }
        return false;
    }

    /**
     * Returns {@code true} if the given type is an {@code AttributeType} or an {@code Operation} computing
     * an attribute, and the attribute value is one of the geometry types recognized by SIS.
     * The types currently recognized by SIS are:
     *
     * <ul>
     *   <li>{@link com.esri.core.geometry.Geometry} of the ESRI's API.</li>
     * </ul>
     *
     * The above list may be expanded in any future SIS version.
     *
     * @param  type  the type to test, or {@code null}.
     * @return {@code true} if the given type is (directly or indirectly) an attribute type
     *         for one of the recognized geometry types.
     *
     * @see #GEOMETRY_PROPERTY
     */
    public static boolean isGeometryAttribute(AbstractIdentifiedType type) {
        while (type instanceof AbstractOperation) {
            type = ((AbstractOperation) type).getResult();
        }
        return (type instanceof DefaultAttributeType<?>) && Geometries.isKnownType(((DefaultAttributeType<?>) type).getValueClass());
    }

    /**
     * Returns whether the given operation or attribute type is characterized by a coordinate reference system.
     * This method verifies whether a characteristic named {@link #CRS_CHARACTERISTIC} with values assignable to
     * {@link CoordinateReferenceSystem} exists (directly or indirectly) for the given type.
     *
     * @param  type  the operation or attribute type for which to get the CRS, or {@code null}.
     * @return {@code true} if a characteristic for Coordinate Reference System has been found.
     */
    public static boolean characterizedByCRS(final AbstractIdentifiedType type) {
        return hasCharacteristic(type, CRS_CHARACTERISTIC.toString(), CoordinateReferenceSystem.class);
    }

    /**
     * Returns the Coordinate Reference Systems characteristic for the given attribute, or {@code null} if none.
     * This method gets the value or default value from the characteristic named {@link #CRS_CHARACTERISTIC}.
     *
     * @param  attribute  the attribute for which to get the CRS, or {@code null}.
     * @return the Coordinate Reference System characteristic of the given attribute, or {@code null} if none.
     * @throws ClassCastException if {@link #CRS_CHARACTERISTIC} has been found but is associated
     *         to an object which is not a {@link CoordinateReferenceSystem} instance.
     *
     * @see org.apache.sis.feature.builder.AttributeTypeBuilder#setCRS(CoordinateReferenceSystem)
     */
    public static CoordinateReferenceSystem getCRSCharacteristic(final Object attribute) {
        return (CoordinateReferenceSystem) getCharacteristic(attribute, CRS_CHARACTERISTIC.toString());
    }

    /**
     * Returns the Coordinate Reference Systems characteristic for the given property type, or {@code null} if none.
     * This method gets the default value from the characteristic named {@link #CRS_CHARACTERISTIC}.
     * If the given property is a link, then this method follows the link in the given feature type (if non-null).
     *
     * <p>This method should be used only when the actual property instance is unknown.
     * Otherwise, {@code getCRSCharacteristic(Property)} should be used because the CRS
     * may vary for each property instance.</p>
     *
     * @param  feature    the feature type in which to follow links, or {@code null} if none.
     * @param  attribute  the attribute type for which to get the CRS, or {@code null}.
     * @return the Coordinate Reference System characteristic of the given property type, or {@code null} if none.
     * @throws ClassCastException if {@link #CRS_CHARACTERISTIC} has been found but is associated
     *         to an object which is not a {@link CoordinateReferenceSystem} instance.
     */
    public static CoordinateReferenceSystem getCRSCharacteristic(final DefaultFeatureType feature, final AbstractIdentifiedType attribute) {
        return (CoordinateReferenceSystem) getCharacteristic(feature, attribute, CRS_CHARACTERISTIC.toString());
    }

    /**
     * Returns whether the given operation or attribute type is characterized by a maximal length.
     * This method verifies whether a characteristic named {@link #MAXIMAL_LENGTH_CHARACTERISTIC}
     * with values of class {@link Integer} exists (directly or indirectly) for the given type.
     *
     * @param  type  the operation or attribute type for which to get the maximal length, or {@code null}.
     * @return {@code true} if a characteristic for maximal length has been found.
     */
    public static boolean characterizedByMaximalLength(final AbstractIdentifiedType type) {
        return hasCharacteristic(type, MAXIMAL_LENGTH_CHARACTERISTIC.toString(), Integer.class);
    }

    /**
     * Returns the maximal length characteristic for the given attribute, or {@code null} if none.
     * This method gets the value or default value from the characteristic named {@link #MAXIMAL_LENGTH_CHARACTERISTIC}.
     *
     * @param  attribute  the attribute for which to get the maximal length, or {@code null}.
     * @return the maximal length characteristic of the given attribute, or {@code null} if none.
     * @throws ClassCastException if {@link #MAXIMAL_LENGTH_CHARACTERISTIC} has been found but is associated
     *         to an object which is not an {@link Integer} instance.
     *
     * @see org.apache.sis.feature.builder.AttributeTypeBuilder#setMaximalLength(Integer)
     */
    public static Integer getMaximalLengthCharacteristic(final Object attribute) {
        return (Integer) getCharacteristic(attribute, MAXIMAL_LENGTH_CHARACTERISTIC.toString());
    }

    /**
     * Returns the maximal length characteristic for the given property type, or {@code null} if none.
     * This method gets the default value from the characteristic named {@link #MAXIMAL_LENGTH_CHARACTERISTIC}.
     * If the given property is a link, then this method follows the link in the given feature type (if non-null).
     *
     * <p>This method should be used only when the actual property instance is unknown.
     * Otherwise, {@code getMaximalLengthCharacteristic(Property)} should be used because
     * the maximal length may vary for each property instance.</p>
     *
     * @param  feature    the feature type in which to follow links, or {@code null} if none.
     * @param  attribute  the attribute type for which to get the maximal length, or {@code null}.
     * @return the maximal length characteristic of the given property type, or {@code null} if none.
     * @throws ClassCastException if {@link #MAXIMAL_LENGTH_CHARACTERISTIC} has been found but is associated
     *         to an object which is not a {@link CoordinateReferenceSystem} instance.
     */
    public static Integer getMaximalLengthCharacteristic(final DefaultFeatureType feature, final AbstractIdentifiedType attribute) {
        return (Integer) getCharacteristic(feature, attribute, MAXIMAL_LENGTH_CHARACTERISTIC.toString());
    }

    /**
     * Returns {@code true} if the given operation or attribute type has a characteristic of the given name,
     * and the values of that characteristic are assignable to the given {@code valueClass}.
     *
     * @param  type        the operation or attribute type for which to test the existence of a characteristic.
     * @param  name        the name of the characteristic to test.
     * @param  valueClass  the expected characteristic values.
     * @return {@code true} if a characteristic of the given name exists and has values assignable to the given class.
     */
    private static boolean hasCharacteristic(AbstractIdentifiedType type, final String name, final Class<?> valueClass) {
        while (type instanceof AbstractOperation) {
            type = ((AbstractOperation) type).getResult();
        }
        if (type instanceof DefaultAttributeType<?>) {
            final DefaultAttributeType<?> at = ((DefaultAttributeType<?>) type).characteristics().get(name);
            if (at != null) {
                return valueClass.isAssignableFrom(at.getValueClass());
            }
        }
        return false;
    }

    /**
     * Fetches from the given property the value or default value of the named characteristic.
     * If the given property is null, or is not an attribute, or does not have characteristics
     * of the given name, then this method returns {@code null}.
     *
     * @param  attribute  the attribute from which to get the characteristic value or default value, or {@code null}.
     * @param  name       name of the characteristic to get.
     * @return the value or default value of the given characteristic in the given property, or {@code null} if none.
     */
    private static Object getCharacteristic(final Object attribute, final String name) {
        if (attribute instanceof AbstractAttribute<?>) {
            final AbstractAttribute<?> at = ((AbstractAttribute<?>) attribute).characteristics().get(name);
            if (at != null) {
                final Object value = at.getValue();
                if (value != null) {
                    return value;
                }
            }
            final DefaultAttributeType<?> type = ((AbstractAttribute<?>) attribute).getType().characteristics().get(name);
            if (type != null) {
                return type.getDefaultValue();
            }
        }
        return null;
    }

    /**
     * Fetches from the given property the default value of the characteristic of the given name.
     * If the given property is a link, then this method follows the link in the given feature type
     * (unless that feature type is null).
     *
     * @param  feature         the feature type in which to follow links, or {@code null} if none.
     * @param  property        the property from which to get the characteristic value, or {@code null}.
     * @param  characteristic  name of the characteristic from which to get the default value.
     * @return the default value of the named characteristic in the given property, or {@code null} if none.
     */
    private static Object getCharacteristic(final DefaultFeatureType feature, AbstractIdentifiedType property, final String characteristic) {
        final String referent = FeatureUtilities.linkOf(property);
        if (referent != null && feature != null) {
            property = feature.getProperty(referent);
        }
        if (property instanceof DefaultAttributeType<?>) {
            final DefaultAttributeType<?> type = ((DefaultAttributeType<?>) property).characteristics().get(characteristic);
            if (type != null) {
                return type.getDefaultValue();
            }
        }
        return null;
    }
}
