/*
 * 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.Map;
import java.util.Iterator;
import org.opengis.util.GenericName;
import org.apache.sis.util.resources.Errors;

// Branch-dependent imports
import org.opengis.feature.PropertyType;


/**
 * Base class of property types having a value and a multiplicity.
 * This include {@code AttributeType} and {@code AssociationRole}, but not {@code Operation}.
 *
 * <div class="note"><b>Analogy:</b> if we compare {@code FeatureType} to a class in the Java language,
 * attributes and associations would be fields while operations would be methods. This analogy explains
 * the {@code FieldType} name of this class.</div>
 *
 * @author  Johann Sorel (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.8
 * @since   0.5
 * @module
 */
abstract class FieldType extends AbstractIdentifiedType implements PropertyType {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = 1681767054884098122L;

    /**
     * The minimum number of occurrences of the property within its containing entity.
     */
    private final int minimumOccurs;

    /**
     * The maximum number of occurrences of the property within its containing entity,
     * or {@link Integer#MAX_VALUE} if there is no limit.
     */
    private final int maximumOccurs;

    /**
     * Constructs a field type from the given properties. The identification map is given unchanged to
     * the {@linkplain AbstractIdentifiedType#AbstractIdentifiedType(Map) super-class constructor}.
     *
     * @param identification  the name and other information to be given to this field type.
     * @param minimumOccurs   the minimum number of occurrences of the property within its containing entity.
     * @param maximumOccurs   the maximum number of occurrences of the property within its containing entity,
     *                        or {@link Integer#MAX_VALUE} if there is no restriction.
     */
    FieldType(final Map<String,?> identification, final int minimumOccurs, final int maximumOccurs) {
        super(identification);
        if (minimumOccurs < 0 || maximumOccurs < minimumOccurs) {
            throw new IllegalArgumentException(Errors.format(
                    Errors.Keys.IllegalRange_2, minimumOccurs, maximumOccurs));
        }
        this.minimumOccurs = minimumOccurs;
        this.maximumOccurs = maximumOccurs;
    }

    /**
     * Returns the minimum number of occurrences of the property within its containing entity.
     * The returned value is greater than or equal to zero.
     *
     * @return the minimum number of occurrences of the property within its containing entity.
     */
    public int getMinimumOccurs() {
        return minimumOccurs;
    }

    /**
     * Returns the maximum number of occurrences of the property within its containing entity.
     * The returned value is greater than or equal to the {@link #getMinimumOccurs()} value.
     * If there is no maximum, then this method returns {@link Integer#MAX_VALUE}.
     *
     * @return the maximum number of occurrences of the property within its containing entity,
     *         or {@link Integer#MAX_VALUE} if none.
     */
    public int getMaximumOccurs() {
        return maximumOccurs;
    }

    /**
     * Returns a hash code value for this property type.
     *
     * @return {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return super.hashCode() + 37*(minimumOccurs + 31*maximumOccurs);
    }

    /**
     * Compares this property type with the given object for equality.
     *
     * @return {@inheritDoc}
     */
    @Override
    public boolean equals(final Object obj) {
        if (super.equals(obj)) {
            final FieldType that = (FieldType) obj;
            return minimumOccurs == that.minimumOccurs &&
                   maximumOccurs == that.maximumOccurs;
        }
        return false;
    }

    /**
     * Helper method for implementation of {@code PropertyType.toString()} methods.
     * Example:
     *
     * {@preformat text
     *     PropertyType[“name” : ValueClass]
     * }
     *
     * @param deprecated  whether the type to format is deprecated.
     * @param className   the interface name of the object on which {@code toString()} is invoked.
     * @param name        the property type name, sometime {@link #getName()} or sometime the name of another object.
     * @param valueType   the name of value class (attribute), or the feature type name (association).
     */
    static StringBuilder toString(final boolean deprecated, final String className, final GenericName name, final Object valueType) {
        final StringBuilder buffer = new StringBuilder(40);
        if (deprecated) {
            buffer.append("Deprecated");
        }
        buffer.append(className).append('[');
        if (name != null) {
            buffer.append('“');
        }
        buffer.append(name);
        if (name != null) {
            buffer.append("” : ");
        }
        return buffer.append(valueType).append(']');
    }

    /**
     * Helper method for implementation of {@code Property.toString()} methods.
     * Example:
     *
     * {@preformat text
     *     Property[“name” : ValueClass] = {value1, value2, ...}
     * }
     *
     * @param deprecated  whether the type to format is deprecated.
     * @param className   the interface name of the object on which {@code toString()} is invoked.
     * @param name        the property type name, sometime {@link #getName()} or sometime the name of another object.
     * @param valueType   the name of value class (attribute), or the feature type name (association).
     * @param values      the actual values.
     */
    static StringBuilder toString(final boolean deprecated, final String className, final GenericName name,
            final Object valueType, final Iterator<?> values)
    {
        final StringBuilder buffer = toString(deprecated, className, name, valueType);
        if (values.hasNext()) {
            final Object value = values.next();
            final boolean isMultiValued = values.hasNext();
            buffer.append(" = ");
            if (isMultiValued) {
                buffer.append('{');
            }
            buffer.append(value);
            if (isMultiValued) {
                buffer.append(", ").append(values.next());
                if (values.hasNext()) {
                    buffer.append(", ...");
                }
                buffer.append('}');
            }
        }
        return buffer;
    }
}
