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

import java.util.Collection;
import java.util.Iterator;
import java.io.Serializable;
import org.opengis.util.GenericName;
import org.opengis.metadata.quality.DataQuality;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.internal.feature.Resources;

// Branch-dependent imports
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureType;
import org.opengis.feature.FeatureAssociation;
import org.opengis.feature.FeatureAssociationRole;
import org.opengis.feature.InvalidPropertyValueException;
import org.opengis.feature.MultiValuedPropertyException;


/**
 * An instance of an {@linkplain DefaultAssociationRole feature association role} containing the associated feature.
 * {@code AbstractAssociation} can be instantiated by calls to {@link DefaultAssociationRole#newInstance()}.
 *
 * <h2>Limitations</h2>
 * <ul>
 *   <li><b>Multi-threading:</b> {@code AbstractAssociation} instances are <strong>not</strong> thread-safe.
 *       Synchronization, if needed, shall be done externally by the caller.</li>
 *   <li><b>Serialization:</b> serialized objects of this class are not guaranteed to be compatible with future
 *       versions. Serialization should be used only for short term storage or RMI between applications running
 *       the same SIS version.</li>
 * </ul>
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 *
 * @see AbstractFeature
 * @see DefaultAssociationRole
 *
 * @since 0.5
 * @module
 */
public abstract class AbstractAssociation extends Field<Feature> implements FeatureAssociation, Cloneable, Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = 5992169056331267867L;

    /**
     * Information about the association.
     */
    final FeatureAssociationRole role;

    /**
     * Creates a new association of the given role.
     *
     * @param role  information about the association.
     *
     * @see #create(FeatureAssociationRole)
     */
    protected AbstractAssociation(final FeatureAssociationRole role) {
        this.role = role;
    }

    /**
     * Creates a new association of the given role.
     *
     * @param  role  information about the association.
     * @return the new association.
     *
     * @see DefaultAssociationRole#newInstance()
     */
    public static AbstractAssociation create(final FeatureAssociationRole role) {
        ArgumentChecks.ensureNonNull("role", role);
        return isSingleton(role.getMaximumOccurs())
               ? new SingletonAssociation(role)
               : new MultiValuedAssociation(role);
    }

    /**
     * Creates a new association of the given role initialized to the given value.
     *
     * @param  role   information about the association.
     * @param  value  the initial value (may be {@code null}).
     * @return the new association.
     */
    static AbstractAssociation create(final FeatureAssociationRole role, final Object value) {
        ArgumentChecks.ensureNonNull("role", role);
        return isSingleton(role.getMaximumOccurs())
               ? new SingletonAssociation(role, (Feature) value)
               : new MultiValuedAssociation(role, value);
    }

    /**
     * Returns the name of this association as defined by its {@linkplain #getRole() role}.
     * This convenience method delegates to {@link FeatureAssociationRole#getName()}.
     *
     * @return the association name specified by its role.
     */
    @Override
    public GenericName getName() {
        return role.getName();
    }

    /**
     * Returns information about the association.
     *
     * @return information about the association.
     */
    @Override
    public FeatureAssociationRole getRole() {
        return role;
    }

    /**
     * Returns the associated feature, or {@code null} if none. This convenience method can be invoked in
     * the common case where the {@linkplain DefaultAssociationRole#getMaximumOccurs() maximum number} of
     * features is restricted to 1 or 0.
     *
     * @return the associated feature (may be {@code null}).
     * @throws MultiValuedPropertyException if this association contains more than one value.
     *
     * @see AbstractFeature#getPropertyValue(String)
     */
    @Override
    public abstract Feature getValue() throws MultiValuedPropertyException;

    /**
     * Returns all features, or an empty collection if none.
     * The returned collection is <cite>live</cite>: changes in the returned collection
     * will be reflected immediately in this {@code Association} instance, and conversely.
     *
     * <p>The default implementation returns a collection which will delegate its work to
     * {@link #getValue()} and {@link #setValue(Object)}.</p>
     *
     * @return the features in a <cite>live</cite> collection.
     */
    @Override
    public Collection<Feature> getValues() {
        return super.getValues();
    }

    /**
     * Sets the associated feature.
     *
     * <h4>Validation</h4>
     * The amount of validation performed by this method is implementation dependent.
     * Usually, only the most basic constraints are verified. This is so for performance reasons
     * and also because some rules may be temporarily broken while constructing a feature.
     * A more exhaustive verification can be performed by invoking the {@link #quality()} method.
     *
     * @param  value  the new value, or {@code null}.
     * @throws InvalidPropertyValueException if the given feature is not valid for this association.
     *
     * @see AbstractFeature#setPropertyValue(String, Object)
     */
    @Override
    public abstract void setValue(final Feature value) throws InvalidPropertyValueException;

    /**
     * Sets the features. All previous values are replaced by the given collection.
     *
     * <p>The default implementation ensures that the given collection contains at most one element,
     * then delegates to {@link #setValue(Feature)}.</p>
     *
     * @param  values  the new values.
     * @throws InvalidPropertyValueException if the given collection contains too many elements.
     */
    @Override
    public void setValues(final Collection<? extends Feature> values) throws InvalidPropertyValueException {
        super.setValues(values);
    }

    /**
     * Ensures that storing a feature of the given type is valid for an association
     * expecting the given base type.
     */
    final void ensureValid(final FeatureType base, final FeatureType type) {
        if (base != type && !DefaultFeatureType.maybeAssignableFrom(base, type)) {
            throw new InvalidPropertyValueException(
                    Resources.format(Resources.Keys.IllegalFeatureType_3, getName(), base.getName(), type.getName()));
        }
    }

    /**
     * Verifies if the current association value mets the constraints defined by the association role.
     * This method returns at most one {@linkplain org.apache.sis.metadata.iso.quality.DefaultDataQuality#getReports()
     * report} with a {@linkplain org.apache.sis.metadata.iso.quality.DefaultDomainConsistency#getResults() result} for
     * each constraint violations found, if any.
     * See {@link AbstractAttribute#quality()} for an example.
     *
     * <p>This association is valid if this method does not report any
     * {@linkplain org.apache.sis.metadata.iso.quality.DefaultConformanceResult conformance result} having a
     * {@linkplain org.apache.sis.metadata.iso.quality.DefaultConformanceResult#pass() pass} value of {@code false}.</p>
     *
     * @return reports on all constraint violations found.
     *
     * @see AbstractFeature#quality()
     */
    public DataQuality quality() {
        final Validator v = new Validator(null);
        v.validate(role, getValues());
        return v.quality;
    }

    /**
     * Returns a string representation of this association.
     * The returned string is for debugging purpose and may change in any future SIS version.
     *
     * @return a string representation of this association for debugging purpose.
     */
    @Override
    public String toString() {
        final String pt = DefaultAssociationRole.getTitleProperty(role);
        final Iterator<Feature> it = getValues().iterator();
        return FieldType.toString(isDeprecated(role), "FeatureAssociation", role.getName(),
                DefaultAssociationRole.getValueTypeName(role), new Iterator<Object>()
        {
            @Override public boolean hasNext() {
                return it.hasNext();
            }

            @Override public Object next() {
                return it.next().getPropertyValue(pt);
            }
        }).toString();
    }

    /**
     * Returns a copy of this association.
     * The default implementation returns a <em>shallow</em> copy:
     * the association {@linkplain #getValue() value} is <strong>not</strong> cloned.
     * However subclasses may choose to do otherwise.
     *
     * @return a clone of this association.
     * @throws CloneNotSupportedException if this association can not be cloned.
     *         The default implementation never throw this exception. However subclasses may throw it.
     */
    @Override
    public AbstractAssociation clone() throws CloneNotSupportedException {
        return (AbstractAssociation) super.clone();
    }
}
