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

import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
import java.time.temporal.Temporal;
import org.opengis.util.ScopedName;
import org.opengis.util.GenericName;
import org.opengis.util.NameFactory;
import org.opengis.util.FactoryException;
import org.opengis.util.InternationalString;
import org.apache.sis.setup.GeometryLibrary;
import org.opengis.metadata.citation.OnlineResource;
import org.opengis.metadata.content.ContentInformation;
import org.opengis.metadata.acquisition.GeometryType;
import org.apache.sis.storage.gps.Fix;
import org.apache.sis.storage.FeatureNaming;
import org.apache.sis.storage.IllegalNameException;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.feature.AbstractIdentifiedType;
import org.apache.sis.feature.FeatureOperations;
import org.apache.sis.feature.builder.FeatureTypeBuilder;
import org.apache.sis.feature.builder.PropertyTypeBuilder;
import org.apache.sis.feature.builder.AttributeRole;
import org.apache.sis.internal.feature.AttributeConvention;
import org.apache.sis.internal.feature.Geometries;
import org.apache.sis.internal.storage.FeatureCatalogBuilder;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.util.iso.ResourceInternationalString;
import org.apache.sis.util.iso.DefaultNameFactory;

// Branch-dependent imports
import org.apache.sis.feature.DefaultFeatureType;
import org.apache.sis.feature.DefaultAttributeType;


/**
 * Feature types that may appear in GPX files. All values defined in this class are immutable and can be shared
 * by many {@link Reader} instances. There is usually only one {@code Types} instance for a running JVM, but we
 * nevertheless allows definition of alternative {@code Types} with names created by different factories.
 *
 * @author  Johann Sorel (Geomatys)
 * @version 0.8
 * @since   0.8
 * @module
 */
final class Types {
    /**
     * The parent of all other feature types.
     */
    final DefaultFeatureType parent;

    /**
     * Way point GPX feature type.
     */
    final DefaultFeatureType wayPoint;

    /**
     * Route GPX feature type.
     */
    final DefaultFeatureType route;

    /**
     * Track GPX feature type.
     */
    final DefaultFeatureType track;

    /**
     * Track segment GPX feature type.
     */
    final DefaultFeatureType trackSegment;

    /**
     * The list of feature types to be given to GPC metadata objects.
     */
    final Collection<ContentInformation> metadata;

    /**
     * Binding from names to feature type instances.
     * Shall not be modified after construction.
     *
     * @deprecated We are not sure yet if we will keep this field. Decision is pending acquisition of
     *             more experience with the API proposed by {@link org.apache.sis.storage.FeatureSet}.
     */
    @Deprecated
    final FeatureNaming<DefaultFeatureType> names;

    /**
     * Accessor to the geometry implementation in use (Java2D, ESRI or JTS).
     */
    final Geometries<?> geometries;

    /**
     * A system-wide instance for {@code FeatureType} instances created using the {@link DefaultNameFactory}.
     * This is normally the only instance used in an application.
     */
    static final Types DEFAULT;
    static {
        try {
            DEFAULT = new Types(DefaultFactories.forBuildin(NameFactory.class, DefaultNameFactory.class), null, null);
        } catch (FactoryException | IllegalNameException e) {
            throw new AssertionError(e);        // Should never happen with DefaultNameFactory implementation.
        }
    }

    /**
     * Creates new {@code FeatureTypes} with feature names and property names created using the given factory.
     *
     * @param  factory   the factory to use for creating names, or {@code null} for the default factory.
     * @param  locale    the locale to use for formatting error messages, or {@code null} for the default locale.
     * @param  library   the required geometry library, or {@code null} for the default.
     * @throws FactoryException if an error occurred while creating an "envelope bounds" operation.
     */
    Types(final NameFactory factory, final Locale locale, final GeometryLibrary library)
            throws FactoryException, IllegalNameException
    {
        geometries = Geometries.implementation(library);
        final Map<String,InternationalString[]> resources = new HashMap<>();
        final ScopedName    geomName = AttributeConvention.GEOMETRY_PROPERTY;
        final Map<String,?> geomInfo = Collections.singletonMap(AbstractIdentifiedType.NAME_KEY, geomName);
        final Map<String,?> envpInfo = Collections.singletonMap(AbstractIdentifiedType.NAME_KEY, AttributeConvention.ENVELOPE_PROPERTY);
        /*
         * The parent of all FeatureTypes to be created in this constructor.
         * This parent has a single property, "sis:identifier" of type Integer,
         * which is not part of GPX specification.
         *
         * GPXEntity
         * ┌────────────────┬─────────┬──────────────┐
         * │ Name           │ Type    │ Multiplicity │
         * ├────────────────┼─────────┼──────────────┤
         * │ sis:identifier │ Integer │   [1 … 1]    │      SIS-specific property
         * └────────────────┴─────────┴──────────────┘
         */
        final FeatureTypeBuilder builder = new FeatureTypeBuilder(factory, library, locale);
        builder.setNameSpace(Tags.PREFIX).setName("GPXEntity").setAbstract(true);
        builder.addAttribute(Integer.class).setName(AttributeConvention.IDENTIFIER_PROPERTY);
        parent = builder.build();
        /*
         * WayPoint ⇾ GPXEntity
         * ┌──────────────────┬────────────────┬───────────────────────┬──────────────┐
         * │ Name             │ Type           │ XML type              │ Multiplicity │
         * ├──────────────────┼────────────────┼───────────────────────┼──────────────┤
         * │ sis:identifier   │ Integer        │                       │   [1 … 1]    │
         * │ sis:envelope     │ Envelope       │                       │   [1 … 1]    │
         * │ sis:geometry     │ Point          │ (lat,lon) attributes  │   [1 … 1]    │
         * │ ele              │ Double         │ xs:decimal            │   [0 … 1]    │
         * │ time             │ Temporal       │ xs:dateTime           │   [0 … 1]    │
         * │ magvar           │ Double         │ gpx:degreesType       │   [0 … 1]    │
         * │ geoidheight      │ Double         │ xs:decimal            │   [0 … 1]    │
         * │ name             │ String         │ xs:string             │   [0 … 1]    │
         * │ cmt              │ String         │ xs:string             │   [0 … 1]    │
         * │ desc             │ String         │ xs:string             │   [0 … 1]    │
         * │ src              │ String         │ xs:string             │   [0 … 1]    │
         * │ link             │ OnlineResource │ gpx:linkType          │   [0 … ∞]    │
         * │ sym              │ String         │ xs:string             │   [0 … 1]    │
         * │ type             │ String         │ xs:string             │   [0 … 1]    │
         * │ fix              │ Fix            │ gpx:fixType           │   [0 … 1]    │
         * │ sat              │ Integer        │ xs:nonNegativeInteger │   [0 … 1]    │
         * │ hdop             │ Double         │ xs:decimal            │   [0 … 1]    │
         * │ vdop             │ Double         │ xs:decimal            │   [0 … 1]    │
         * │ pdop             │ Double         │ xs:decimal            │   [0 … 1]    │
         * │ ageofdgpsdata    │ Double         │ xs:decimal            │   [0 … 1]    │
         * │ dgpsid           │ Integer        │ gpx:dgpsStationType   │   [0 … 1]    │
         * └──────────────────┴────────────────┴───────────────────────┴──────────────┘
         */
        builder.clear().setSuperTypes(parent).setNameSpace(Tags.PREFIX).setName("WayPoint");
        builder.addAttribute(GeometryType.POINT).setName(geomName)
                .setCRS(CommonCRS.WGS84.normalizedGeographic())
                .addRole(AttributeRole.DEFAULT_GEOMETRY);
        builder.setDefaultMultiplicity(0, 1);
        builder.addAttribute(Double        .class).setName(Tags.ELEVATION);
        builder.addAttribute(Temporal      .class).setName(Tags.TIME);
        builder.addAttribute(Double        .class).setName(Tags.MAGNETIC_VAR);
        builder.addAttribute(Double        .class).setName(Tags.GEOID_HEIGHT);
        builder.addAttribute(String        .class).setName(Tags.NAME);
        builder.addAttribute(String        .class).setName(Tags.COMMENT);
        builder.addAttribute(String        .class).setName(Tags.DESCRIPTION);
        builder.addAttribute(String        .class).setName(Tags.SOURCE);
        builder.addAttribute(OnlineResource.class).setName(Tags.LINK).setMaximumOccurs(Integer.MAX_VALUE);
        builder.addAttribute(String        .class).setName(Tags.SYMBOL);
        builder.addAttribute(String        .class).setName(Tags.TYPE);
        builder.addAttribute(Fix           .class).setName(Tags.FIX);
        builder.addAttribute(Integer       .class).setName(Tags.SATELITTES);
        builder.addAttribute(Double        .class).setName(Tags.HDOP);
        builder.addAttribute(Double        .class).setName(Tags.VDOP);
        builder.addAttribute(Double        .class).setName(Tags.PDOP);
        builder.addAttribute(Double        .class).setName(Tags.AGE_OF_GPS_DATA);
        builder.addAttribute(Integer       .class).setName(Tags.DGPS_ID);
        wayPoint = create(builder, resources);
        /*
         * Route ⇾ GPXEntity
         * ┌────────────────┬────────────────┬───────────────────────┬──────────────┐
         * │ Name           │ Type           │ XML type              │ Multiplicity │
         * ├────────────────┼────────────────┼───────────────────────┼──────────────┤
         * │ sis:identifier │ Integer        │                       │   [1 … 1]    │
         * │ sis:envelope   │ Envelope       │                       │   [1 … 1]    │
         * │ sis:geometry   │ Polyline       │                       │   [1 … 1]    │
         * │ name           │ String         │ xs:string             │   [0 … 1]    │
         * │ cmt            │ String         │ xs:string             │   [0 … 1]    │
         * │ desc           │ String         │ xs:string             │   [0 … 1]    │
         * │ src            │ String         │ xs:string             │   [0 … 1]    │
         * │ link           │ OnlineResource │ gpx:linkType          │   [0 … ∞]    │
         * │ number         │ Integer        │ xs:nonNegativeInteger │   [0 … 1]    │
         * │ type           │ String         │ xs:string             │   [0 … 1]    │
         * │ rtept          │ WayPoint       │ gpx:wptType           │   [0 … ∞]    │
         * └────────────────┴────────────────┴───────────────────────┴──────────────┘
         */
        final DefaultAttributeType<?> groupResult = GroupAsPolylineOperation.getResult(geometries);
        GroupAsPolylineOperation groupOp = new GroupAsPolylineOperation(geomInfo, Tags.ROUTE_POINTS, groupResult);
        builder.clear().setSuperTypes(parent).setNameSpace(Tags.PREFIX).setName("Route");
        builder.addProperty(groupOp);
        builder.addProperty(FeatureOperations.envelope(envpInfo, null, groupOp));
        builder.setDefaultMultiplicity(0, 1);
        builder.addProperty(wayPoint.getProperty(Tags.NAME));
        builder.addProperty(wayPoint.getProperty(Tags.COMMENT));
        builder.addProperty(wayPoint.getProperty(Tags.DESCRIPTION));
        builder.addProperty(wayPoint.getProperty(Tags.SOURCE));
        builder.addProperty(wayPoint.getProperty(Tags.LINK));
        builder.addAttribute(Integer.class).setName(Tags.NUMBER);
        builder.addProperty(wayPoint.getProperty(Tags.TYPE));
        builder.addAssociation(wayPoint).setName(Tags.ROUTE_POINTS).setMaximumOccurs(Integer.MAX_VALUE);
        route = create(builder, resources);
        /*
         * TrackSegment ⇾ GPXEntity
         * ┌────────────────┬──────────┬─────────────┬──────────────┐
         * │ Name           │ Type     │ XML type    │ Multiplicity │
         * ├────────────────┼──────────┼─────────────┼──────────────┤
         * │ sis:identifier │ Integer  │             │   [1 … 1]    │
         * │ sis:envelope   │ Envelope │             │   [1 … 1]    │
         * │ sis:geometry   │ Polyline │             │   [1 … 1]    │
         * │ trkpt          │ WayPoint │ gpx:wptType │   [0 … ∞]    │
         * └────────────────┴──────────┴─────────────┴──────────────┘
         */
        groupOp = new GroupAsPolylineOperation(geomInfo, Tags.TRACK_POINTS, groupResult);
        builder.clear().setSuperTypes(parent).setNameSpace(Tags.PREFIX).setName("TrackSegment");
        builder.addProperty(groupOp);
        builder.addProperty(FeatureOperations.envelope(envpInfo, null, groupOp));
        builder.setDefaultMultiplicity(0, 1);
        builder.addAssociation(wayPoint).setName(Tags.TRACK_POINTS).setMaximumOccurs(Integer.MAX_VALUE);
        trackSegment = create(builder, resources);
        /*
         * Track ⇾ GPXEntity
         * ┌────────────────┬────────────────┬───────────────────────┬──────────────┐
         * │ Name           │ Type           │ XML type              │ Multiplicity │
         * ├────────────────┼────────────────┼───────────────────────┼──────────────┤
         * │ sis:identifier │ Integer        │                       │   [1 … 1]    │
         * │ sis:envelope   │ Envelope       │                       │   [1 … 1]    │
         * │ sis:geometry   │ Polyline       │                       │   [1 … 1]    │
         * │ name           │ String         │ xs:string             │   [0 … 1]    │
         * │ cmt            │ String         │ xs:string             │   [0 … 1]    │
         * │ desc           │ String         │ xs:string             │   [0 … 1]    │
         * │ src            │ String         │ xs:string             │   [0 … 1]    │
         * │ link           │ OnlineResource │ gpx:linkType          │   [0 … ∞]    │
         * │ number         │ Integer        │ xs:nonNegativeInteger │   [0 … 1]    │
         * │ type           │ String         │ xs:string             │   [0 … 1]    │
         * │ trkseg         │ TrackSegment   │ gpx:trksegType        │   [0 … ∞]    │
         * └────────────────┴────────────────┴───────────────────────┴──────────────┘
         */
        groupOp = new GroupAsPolylineOperation(geomInfo, Tags.TRACK_SEGMENTS, groupResult);
        builder.clear().setSuperTypes(parent).setNameSpace(Tags.PREFIX).setName("Track");
        builder.addProperty(groupOp);
        builder.addProperty(FeatureOperations.envelope(envpInfo, null, groupOp));
        builder.setDefaultMultiplicity(0, 1);
        builder.addProperty(route.getProperty(Tags.NAME));
        builder.addProperty(route.getProperty(Tags.COMMENT));
        builder.addProperty(route.getProperty(Tags.DESCRIPTION));
        builder.addProperty(route.getProperty(Tags.SOURCE));
        builder.addProperty(route.getProperty(Tags.LINK));
        builder.addProperty(route.getProperty(Tags.NUMBER));
        builder.addProperty(route.getProperty(Tags.TYPE));
        builder.addAssociation(trackSegment).setName(Tags.TRACK_SEGMENTS).setMaximumOccurs(Integer.MAX_VALUE);
        track = create(builder, resources);

        final FeatureCatalogBuilder fc = new FeatureCatalogBuilder(null);
        fc.define(route);
        fc.define(track);
        fc.define(wayPoint);
        metadata = fc.build(true).getContentInfo();
        names = fc.features;
    }

    /**
     * Adds internationalized designation and definition information for all properties in the given type.
     * Then, returns the result of {@link FeatureTypeBuilder#build()}.
     *
     * @param  builder   the feature type builder for which to add designations and definitions.
     * @param  previous  previously created international strings as array of length 2.
     *                   The first element is the designation and the second element is the definition.
     */
    private static DefaultFeatureType create(final FeatureTypeBuilder builder, final Map<String,InternationalString[]> previous) {
        for (final PropertyTypeBuilder p : builder.properties()) {
            final GenericName name = p.getName();
            if (!AttributeConvention.contains(name)) {
                final InternationalString[] resources = previous.computeIfAbsent(name.toString(), (key) -> new InternationalString[] {
                    new ResourceInternationalString("org.apache.sis.internal.storage.gpx.Designations", key),
                    new ResourceInternationalString("org.apache.sis.internal.storage.gpx.Definitions",  key)
                });
                p.setDefinition (resources[1]);
                p.setDesignation(resources[0]);
            }
        }
        return builder.build();
    }
}
