/*
 * 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.metadata.iso.identification;

import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.identification.AggregateInformation;
import org.opengis.metadata.identification.AssociationType;
import org.opengis.metadata.identification.InitiativeType;
import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.internal.metadata.Dependencies;
import org.apache.sis.internal.xml.LegacyNamespaces;
import org.apache.sis.internal.jaxb.code.DS_AssociationTypeCode;
import org.apache.sis.internal.jaxb.code.DS_InitiativeTypeCode;


/**
 * Associated resource information.
 * The following properties are mandatory or conditional (i.e. mandatory under some circumstances)
 * in a well-formed metadata according ISO 19115:
 *
 * <div class="preformat">{@code MD_AggregateInformation}
 * {@code   ├─associationType…………} Type of relation between the resources.
 * {@code   ├─metadataReference……} Reference to the metadata of the associated resource.
 * {@code   │   ├─title…………………………} Name by which the cited resource is known.
 * {@code   │   └─date……………………………} Reference date for the cited resource.
 * {@code   └─name………………………………………} Citation information about the associated resource.</div>
 *
 * According ISO 19115, at least one of {@linkplain #getName() name} and
 * {@linkplain #getMetadataReference() metadata reference} shall be provided.
 *
 * <div class="warning"><b>Upcoming API change — renaming</b><br>
 * As of ISO 19115:2014, {@code AggregateInformation} has been renamed {@code AssociatedResource}.
 * This class will be replaced by {@link DefaultAssociatedResource} when GeoAPI will provide the
 * {@code AssociatedResource} interface (tentatively in GeoAPI 3.1 or 4.0).
 * </div>
 *
 * <h2>Limitations</h2>
 * <ul>
 *   <li>Instances of this class are not synchronized for multi-threading.
 *       Synchronization, if needed, is caller's responsibility.</li>
 *   <li>Serialized objects of this class are not guaranteed to be compatible with future Apache SIS releases.
 *       Serialization support is appropriate for short term storage or RMI between applications running the
 *       same version of Apache SIS. For long term storage, use {@link org.apache.sis.xml.XML} instead.</li>
 * </ul>
 *
 * @author  Guilhem Legal (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @author  Cullen Rombach (Image Matters)
 * @version 1.0
 * @since   0.3
 * @module
 */
@XmlType(name = "MD_AggregateInformation_Type", namespace = LegacyNamespaces.GMD, propOrder = {
    "aggregateDataSetName",
    "aggregateDataSetIdentifier",
    "association",                  // Actually "associationType", in replacement of the one defined in parent class.
    "initiative"                    // Actually "initiativeType", ibid.
})
@XmlRootElement(name = "MD_AggregateInformation", namespace = LegacyNamespaces.GMD)
public class DefaultAggregateInformation extends DefaultAssociatedResource implements AggregateInformation {
    /**
     * Serial number for compatibility with different versions.
     */
    private static final long serialVersionUID = -8769840909779188495L;

    /**
     * Constructs an initially empty Aggregate dataset information.
     */
    public DefaultAggregateInformation() {
    }

    /**
     * Constructs a new instance initialized with the values from the specified metadata object.
     *
     * @param object The metadata to copy values from.
     */
    DefaultAggregateInformation(final DefaultAssociatedResource object) {
        super(object);
    }

    /**
     * Constructs a new instance initialized with the values from the specified metadata object.
     * This is a <cite>shallow</cite> copy constructor, since the other metadata contained in the
     * given object are not recursively copied.
     *
     * @param  object  the metadata to copy values from, or {@code null} if none.
     */
    public DefaultAggregateInformation(final AggregateInformation object) {
        super(object);
        if (object != null && !(object instanceof DefaultAssociatedResource)) {
            setAggregateDataSetName(object.getAggregateDataSetName());
            setAggregateDataSetIdentifier(object.getAggregateDataSetIdentifier());
        }
    }

    /**
     * Returns a SIS metadata implementation with the values of the given arbitrary implementation.
     * This method performs the first applicable action in the following choices:
     *
     * <ul>
     *   <li>If the given object is {@code null}, then this method returns {@code null}.</li>
     *   <li>Otherwise if the given object is already an instance of
     *       {@code DefaultAggregateInformation}, then it is returned unchanged.</li>
     *   <li>Otherwise a new {@code DefaultAggregateInformation} instance is created using the
     *       copy constructor
     *       and returned. Note that this is a <cite>shallow</cite> copy operation, since the other
     *       metadata contained in the given object are not recursively copied.</li>
     * </ul>
     *
     * @param  object  the object to get as a SIS implementation, or {@code null} if none.
     * @return a SIS implementation containing the values of the given object (may be the
     *         given object itself), or {@code null} if the argument was null.
     */
    public static DefaultAggregateInformation castOrCopy(final AggregateInformation object) {
        if (object == null || object instanceof DefaultAggregateInformation) {
            return (DefaultAggregateInformation) object;
        }
        return new DefaultAggregateInformation(object);
    }

    /**
     * Citation information about the aggregate dataset.
     *
     * @return citation information about the aggregate dataset, or {@code null}.
     *
     * @deprecated As of ISO 19115:2014, replaced by {@link #getName()}.
     */
    @Override
    @Deprecated
    @Dependencies("getName")
    @XmlElement(name = "aggregateDataSetName")
    public Citation getAggregateDataSetName() {
        return getName();
    }

    /**
     * Sets the citation information about the aggregate dataset.
     *
     * @param  newValue  the new citation.
     *
     * @deprecated As of ISO 19115:2014, replaced by {@link #setName(Citation)}.
     */
    @Deprecated
    public void setAggregateDataSetName(final Citation newValue) {
        setName(newValue);
    }

    /**
     * Identification information about aggregate dataset.
     *
     * @return identification information about aggregate dataset, or {@code null}.
     *
     * @deprecated As of ISO 19115:2014, replaced by the first identifier of {@link #getAggregateDataSetName()}.
     */
    @Override
    @Deprecated
    @Dependencies("getName")
    @XmlElement(name = "aggregateDataSetIdentifier")
    public Identifier getAggregateDataSetIdentifier() {
        return getAggregateDataSetIdentifier(getAggregateDataSetName());
    }

    /**
     * Returns the first identifier of the given citation.
     */
    private static Identifier getAggregateDataSetIdentifier(final Citation name) {
        if (name != null) {
            final Collection<? extends Identifier> names = name.getIdentifiers();
            if (names != null) { // May be null on XML marshalling.
                final Iterator<? extends Identifier> it = names.iterator();
                if (it.hasNext()) {
                    return it.next();
                }
            }
        }
        return null;
    }

    /**
     * Sets the identification information about aggregate dataset.
     *
     * @param  newValue  the new identifier.
     *
     * @deprecated As of ISO 19115:2014, replaced by an identifier of {@link #getAggregateDataSetName()}.
     */
    @Deprecated
    public void setAggregateDataSetIdentifier(final Identifier newValue) {
        checkWritePermission(super.getName());
        Citation name = getAggregateDataSetName();
        if (newValue != null) {
            if (!(name instanceof DefaultCitation)) {
                name = new DefaultCitation(name);
                setAggregateDataSetName(name);
            }
            /*
             * If there is more than one value, replace only the first one and keep all other ones unchanged.
             * The intent is to be consistent with the getter method, which returns the first element.
             */
            final ArrayList<Identifier> identifiers = new ArrayList<>(name.getIdentifiers());
            if (identifiers.isEmpty()) {
                identifiers.add(newValue);
            } else {
                identifiers.set(0, newValue);
            }
            ((DefaultCitation) name).setIdentifiers(identifiers);
        } else if (name != null) {
            final Iterator<? extends Identifier> it = name.getIdentifiers().iterator();
            if (it.hasNext()) {
                it.next();
                it.remove();
            }
        }
    }




    //////////////////////////////////////////////////////////////////////////////////////////////////
    ////////                                                                                  ////////
    ////////                               XML support with JAXB                              ////////
    ////////                                                                                  ////////
    ////////        The following methods are invoked by JAXB using reflection (even if       ////////
    ////////        they are private) or are helpers for other methods invoked by JAXB.       ////////
    ////////        Those methods can be safely removed if Geographic Markup Language         ////////
    ////////        (GML) support is not needed.                                              ////////
    ////////                                                                                  ////////
    //////////////////////////////////////////////////////////////////////////////////////////////////


    /**
     * For (un)marshalling the {@code associationType} element at the location expected by ISO 19139:2007 schemas.
     * We do not rely on {@code org.apache.sis.xml.TransformingWriter} reordering mechanism because this element
     * is interleaved with other element to reorder (namely {@code "topicCategory"} and {@code "extent"}), and
     * expanding {@code TransformingWriter} to handle those cases would be complicated.
     */
    @XmlElement(name = "associationType")
    @XmlJavaTypeAdapter(DS_AssociationTypeCode.class)
    private AssociationType getAssociation() {
        return getAssociationType();
    }

    /** Must be declared together with {@link #getAssociation()}. */
    @SuppressWarnings("unused")
    private void setAssociation(final AssociationType newValue) {
        setAssociationType(newValue);
    }

    /**
     * For (un)marshalling the {@code initiativeType} element at the location expected by ISO 19139:2007 schemas.
     * See {@link #getAssociation()} for more explanation.
     */
    @XmlElement(name = "initiativeType")
    @XmlJavaTypeAdapter(DS_InitiativeTypeCode.class)
    private InitiativeType getInitiative() {
        return getInitiativeType();
    }

    /** Must be declared together with {@link #getInitiative()}. */
    @SuppressWarnings("unused")
    private void setInitiative(final InitiativeType newValue) {
        setInitiativeType(newValue);
    }
}
