/*
 * 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.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.io.IOException;
import java.io.UncheckedIOException;
import javax.xml.bind.annotation.XmlList;
import javax.xml.bind.annotation.XmlElement;

import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.citation.CitationDate;
import org.opengis.metadata.citation.DateType;
import org.opengis.metadata.citation.OnlineResource;
import org.opengis.metadata.constraint.Constraints;
import org.opengis.metadata.constraint.LegalConstraints;
import org.opengis.metadata.extent.Extent;
import org.opengis.metadata.identification.Keywords;
import org.opengis.metadata.identification.Identification;
import org.opengis.metadata.content.ContentInformation;
import org.opengis.metadata.distribution.Format;
import org.opengis.referencing.ReferenceSystem;
import org.opengis.util.InternationalString;

import org.apache.sis.io.TableAppender;
import org.apache.sis.internal.simple.SimpleMetadata;
import org.apache.sis.internal.util.UnmodifiableArrayList;
import org.apache.sis.metadata.iso.citation.DefaultCitationDate;
import org.apache.sis.metadata.iso.identification.DefaultKeywords;
import org.apache.sis.metadata.iso.extent.Extents;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.util.iso.SimpleInternationalString;
import org.apache.sis.util.iso.Types;

// Branch-dependent imports
import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.metadata.iso.identification.AbstractIdentification;
import org.opengis.metadata.citation.ResponsibleParty;


/**
 * Information about the GPX file, author, and copyright restrictions.
 * This is the root of the {@code <metadata>} element in a GPX file.
 * At most one such element may appear in the document.
 * The XML content is like below:
 *
 * {@preformat xml
 *   <metadata>
 *     <name> String </name>
 *     <desc> String </desc>
 *     <author> Person </author>
 *     <copyright> Copyright </copyright>
 *     <link href="URI"/>
 *     <time> Temporal </time>
 *     <keywords> String[] </keywords>
 *     <bounds> Envelope </bounds>
 *     <extensions> any object known to JAXB </extensions>
 *   </metadata>
 * }
 *
 * Those properties can be read or modified directly. All methods defined in this class are bridges to
 * the ISO 19115 metadata model and can be ignored if the user only wants to manipulate the GPX model.
 *
 * @author  Johann Sorel (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 * @since   0.8
 * @module
 */
public final class Metadata extends SimpleMetadata {
    /**
     * The data store that created this metadata, or {@code null} if none. This information is used for fetching
     * information that are constants for all GPX files, for example the feature types and the format description.
     *
     * <p>This field needs to be set after construction. It can not be set at construction time because JAXB needs
     * to invoke a no-argument constructor.</p>
     */
    Store store;

    /**
     * The creator of the GPX file. The creator is a property of the GPX node;
     * it is not part of the content marshalled in a GPX {@code <metadata>} element.
     */
    public String creator;

    /**
     * The name of the GPX file.
     *
     * @see #getTitle()
     */
    @XmlElement(name = Tags.NAME)
    public String name;

    /**
     * A description of the contents of the GPX file.
     *
     * @see #getAbstract()
     */
    @XmlElement(name = Tags.DESCRIPTION)
    public String description;

    /**
     * The person or organization who created the GPX file.
     *
     * @see #getPointOfContacts()
     */
    @XmlElement(name = Tags.AUTHOR)
    public Person author;

    /**
     * Copyright and license information governing use of the file.
     *
     * @see #getResourceConstraints()
     */
    @XmlElement(name = Tags.COPYRIGHT)
    public Copyright copyright;

    /**
     * URLs associated with the location described in the file, or {@code null} if none.
     */
    @XmlElement(name = Tags.LINK)
    public List<Link> links;

    /**
     * The creation date of the file.
     *
     * @see #getDates()
     *
     * @todo We would like to use {@link java.time}, but it does not yet work out-of-the-box with JAXB
     *       (we need adapter). Furthermore current GeoAPI interfaces does not yet use {@code java.time}.
     */
    @XmlElement(name = Tags.TIME)
    public Date time;

    /**
     * Keywords associated with the file, or {@code null} if unspecified.
     * Search engines or databases can use this information to classify the data.
     *
     * @see #getDescriptiveKeywords()
     */
    @XmlList
    @XmlElement(name = Tags.KEYWORDS)
    public List<String> keywords;

    /**
     * Minimum and maximum coordinates which describe the extent of the coordinates in the file.
     * The GPX 1.1 specification restricts the coordinate reference system to WGS84.
     *
     * @see #getExtents()
     */
    @XmlElement(name = Tags.BOUNDS)
    public Bounds bounds;

    /**
     * The format returned by {@link #getResourceFormats()}, created when first needed.
     *
     * @see #getResourceFormats()
     */
    private Format format;

    /**
     * Creates an initially empty metadata object.
     */
    public Metadata() {
    }

    /**
     * Copies properties from the given ISO 19115 metadata.
     * If a property has more than one value, only the first one will be retained
     * (except for links and keywords where multi-values are allowed).
     */
    Metadata(final org.opengis.metadata.Metadata md, final Locale locale) {
        for (final Identification id : md.getIdentificationInfo()) {
            /*
             * identificationInfo.citation.title                    →   name
             * identificationInfo.citation.date.date                →   time
             * identificationInfo.citation.onlineResource.name      →   link.text
             * identificationInfo.citation.onlineResource.linkage   →   link.uri
             * identificationInfo.abstract                          →   description
             */
            final Citation ci = id.getCitation();
            if (ci != null) {
                if (name == null) {
                    name = Types.toString(ci.getTitle(), locale);
                }
                if (time == null) {
                    for (final CitationDate d : ci.getDates()) {
                        time = d.getDate();
                        if (time != null) break;
                    }
                }
                if (ci instanceof DefaultCitation) {
                    for (final OnlineResource r : ((DefaultCitation) ci).getOnlineResources()) {
                        links = addIfNonNull(links, Link.castOrCopy(r, locale));
                    }
                }
            }
            if (description == null) {
                description = Types.toString(id.getAbstract(), locale);
            }
            /*
             * identificationInfo.pointOfContact.party.name   →   creator        if role is ORIGINATOR
             * identificationInfo.pointOfContact.party.name   →   author.name    if role is AUTHOR
             */
            for (final ResponsibleParty r : id.getPointOfContacts()) {
                final Person p = Person.castOrCopy(r, locale);
                if (p != null) {
                    if (p.isCreator) {
                        if (creator == null) {
                            creator = p.name;
                        }
                    } else if (author == null) {
                        author = p;
                    }
                }
            }
            /*
             * identificationInfo.resourceConstraints.responsibleParty.party.name        →   copyright.author
             * identificationInfo.resourceConstraints.reference.date.date                →   copyright.year
             * identificationInfo.resourceConstraints.reference.onlineResource.linkage   →   copyright.license
             */
            if (copyright == null) {
                for (final Constraints c : id.getResourceConstraints()) {
                    if (c instanceof LegalConstraints) {
                        copyright = Copyright.castOrCopy((LegalConstraints) c, locale);
                        if (copyright != null) break;
                    }
                }
            }
            /*
             * identificationInfo.descriptiveKeywords.keyword   →   keywords
             */
            for (final Keywords k : id.getDescriptiveKeywords()) {
                for (final InternationalString word : k.getKeywords()) {
                    keywords = addIfNonNull(keywords, Types.toString(word, locale));
                }
            }
            /*
             * identificationInfo.extent.geographicElement   →   bounds
             */
            if (bounds == null && id instanceof AbstractIdentification) {
                for (final Extent e : ((AbstractIdentification) id).getExtents()) {
                    bounds = Bounds.castOrCopy(Extents.getGeographicBoundingBox(e));
                    if (bounds != null) break;
                }
            }
        }
    }

    /**
     * Returns the given ISO 19115 metadata as a {@code Metadata} instance.
     * This method copies the data only if needed.
     *
     * @param  md      the ISO 19115 metadata, or {@code null}.
     * @param  locale  the locale to use for localized strings.
     * @return the GPX metadata, or {@code null}.
     */
    public static Metadata castOrCopy(final org.opengis.metadata.Metadata md, final Locale locale) {
        return (md == null || md instanceof Metadata) ? (Metadata) md : new Metadata(md, locale);
    }

    /**
     * ISO 19115 metadata property determined by the {@link #name} field.
     * This is part of the information returned by {@link #getCitation()}.
     *
     * @return the cited resource name.
     */
    @Override
    public InternationalString getTitle() {
        return (name != null) ? new SimpleInternationalString(name) : super.getTitle();
    }

    /**
     * ISO 19115 metadata property determined by the {@link #description} field.
     * This is part of the information returned by {@link #getIdentificationInfo()}.
     *
     * @return brief narrative summary of the resource.
     */
    @Override
    public InternationalString getAbstract() {
        return (description != null) ? new SimpleInternationalString(description) : super.getAbstract();
    }

    /**
     * ISO 19115 metadata property determined by the {@link #keywords} field.
     * This is part of the information returned by {@link #getIdentificationInfo()}.
     *
     * @return category keywords, their type, and reference source.
     */
    @Override
    public Collection<Keywords> getDescriptiveKeywords() {
        if (keywords != null) {
            return Collections.singletonList(new DefaultKeywords(keywords.toArray(new String[keywords.size()])));
        }
        return Collections.emptyList();
    }

    /**
     * ISO 19115 metadata property determined by the {@link #author} field.
     * This is part of the information returned by {@link #getIdentificationInfo()}.
     *
     * @return means of communication with person(s) and organisations(s) associated with the resource.
     */
    @Override
    public Collection<ResponsibleParty> getPointOfContacts() {
        if (creator != null) {
            final Person p = new Person(creator);
            return (author != null) ? UnmodifiableArrayList.wrap(new ResponsibleParty[] {p, author})
                                    : Collections.singletonList(author);
        }
        return (author != null) ? Collections.singletonList(author) : Collections.emptyList();
    }

    /**
     * ISO 19115 metadata property determined by the {@link #copyright} field.
     * This is part of the information returned by {@link #getIdentificationInfo()}.
     *
     * @return constraints which apply to the resource(s).
     */
    @Override
    public Collection<Constraints> getResourceConstraints() {
        return (copyright != null) ? Collections.singletonList(copyright) : Collections.emptyList();
    }

    /**
     * ISO 19115 metadata property determined by the {@link #bounds} field.
     * This is part of the information returned by {@link #getIdentificationInfo()}.
     *
     * @return spatial and temporal extent of the resource.
     */
    @Override
    public Collection<Extent> getExtents() {
        return (bounds != null) ? Collections.singletonList(bounds) : Collections.emptyList();
    }

    /**
     * Description of the spatial and temporal reference systems used in the dataset.
     * This is fixed to WGS 84 in GPX files. We use (latitude, longitude) axis order.
     *
     * @return WGS 84 (EPSG:4326).
     */
    @Override
    public Collection<ReferenceSystem> getReferenceSystemInfo() {
        return Collections.singletonList(CommonCRS.WGS84.geographic());
    }

    /**
     * ISO 19115 metadata property determined by the {@link #time} field.
     * This is part of the information returned by {@link #getCitation()}.
     *
     * @return reference dates for the cited resource.
     */
    @Override
    public Collection<CitationDate> getDates() {
        if (time != null) {
            return Collections.singletonList(new DefaultCitationDate(time, DateType.CREATION));
        }
        return Collections.emptyList();
    }

    /**
     * Names of features types available for the GPX format, or an empty list if none.
     * This property is not part of metadata described in GPX file; it is rather a hard-coded value shared by all
     * GPX files. Users could however filter the list of features, for example with only routes and no tracks.
     *
     * @return information about the feature characteristics.
     */
    @Override
    public Collection<ContentInformation> getContentInfo() {
        final Store store = this.store;
        return (store != null) ? store.types.metadata : Collections.emptyList();
    }

    /**
     * Description of the format of the resource(s).
     * This is part of the information returned by {@link #getIdentificationInfo()}.
     *
     * @return description of the format of the resource(s).
     */
    @Override
    public Collection<Format> getResourceFormats() {
        final Store store = this.store;
        if (store != null) {
            Format f;
            synchronized (store) {
                if ((f = format) == null) {
                    format = f = store.getFormat();
                }
            }
            return Collections.singletonList(f);
        }
        return Collections.emptyList();
    }

    /**
     * Compares this {@code Metadata} with the given object for equality.
     *
     * @param  obj  the object to compare with this {@code Metadata}.
     * @return {@code true} if both objects are equal.
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof Metadata) {
            final Metadata that = (Metadata) obj;
            return Objects.equals(this.creator,     that.creator)     &&
                   Objects.equals(this.name,        that.name)        &&
                   Objects.equals(this.description, that.description) &&
                   Objects.equals(this.author,      that.author)      &&
                   Objects.equals(this.copyright,   that.copyright)   &&
                   Objects.equals(this.links,       that.links)       &&
                   Objects.equals(this.time,        that.time)        &&
                   Objects.equals(this.keywords,    that.keywords)    &&
                   Objects.equals(this.bounds,      that.bounds);
        }
        return false;
    }

    /**
     * Returns a hash code value for this {@code Metadata}.
     *
     * @return a hash code value.
     */
    @Override
    public int hashCode() {
        return Objects.hash(creator, name, description, author, copyright, links, time, keywords, bounds);
    }

    /**
     * Returns a string representation of this metadata object.
     *
     * @return a string representation of this metadata.
     */
    @Override
    public String toString() {
        final StringBuilder buffer = new StringBuilder();
        buffer.append("GPX metadata").append(System.lineSeparator());
        final TableAppender table = new TableAppender(buffer);
        table.setMultiLinesCells(true);
        table.appendHorizontalSeparator();
        append(table, "Creator",     creator);
        append(table, "Name",        name);
        append(table, "Description", description);
        append(table, "Author",      author);
        append(table, "Copyright",   copyright);
        append(table, "Link(s)",     links, System.lineSeparator());
        append(table, "Time",        (time != null) ? time.toInstant() : null);
        append(table, "Keywords",    keywords, " ");
        append(table, "Bounds",      bounds);
        table.appendHorizontalSeparator();
        try {
            table.flush();
        } catch (IOException e) {
            throw new UncheckedIOException(e);      // Should never happen since we are writing to a StringBuilder.
        }
        return buffer.toString();
    }

    /**
     * Appends a row to the given table if the given value is non-null.
     *
     * @param  table  the table where to append a row.
     * @param  label  the label.
     * @param  value  the value, or {@code null} if none.
     */
    private static void append(final TableAppender table, final String label, final Object value) {
        if (value != null) {
            table.append(label).append(':').nextColumn();
            table.append(value.toString()).nextLine();
        }
    }

    /**
     * Appends a multi-values to the given table if the given list is non-null.
     *
     * @param  table      the table where to append a row.
     * @param  label      the label.
     * @param  values     the values, or {@code null} if none.
     * @param  separator  the separator to insert between each value.
     */
    private static void append(final TableAppender table, final String label, final List<?> values, final String separator) {
        if (values != null && !values.isEmpty()) {
            table.append(label).append(':').nextColumn();
            final int n = values.size();
            for (int i=0; i<n; i++) {
                if (i != 0) table.append(separator);
                table.append(values.get(i).toString());
            }
            table.nextLine();
        }
    }

    /**
     * Adds the given element to the given list if non null, or do nothing otherwise.
     * This is a convenience method for storing {@code <link>} elements in way points,
     * routes or tracks among others.
     *
     * @param  list     the list where to add the element, or {@code null} if not yet created.
     * @param  element  the element to add, or {@code null} if none.
     * @return the list where the element has been added.
     */
    static <T> List<T> addIfNonNull(List<T> list, final T element) {
        if (element != null) {
            if (list == null) {
                list = new ArrayList<>(4);         // Small capacity since there is usually few elements.
            }
            list.add(element);
        }
        return list;
    }
}
