// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
package com.ibm.icu.text;

import java.text.Format.Field;
import java.util.Objects;

/**
 * Represents a span of a string containing a given field.
 *
 * This class differs from FieldPosition in the following ways:
 *
 *   1. It has information on the field category.
 *   2. It allows you to set constraints to use when iterating over field positions.
 *   3. It is used for the newer FormattedValue APIs.
 *
 * @author sffc
 * @draft ICU 64
 * @provisional This API might change or be removed in a future release.
 */
public class ConstrainedFieldPosition {

    /**
     * Represents the type of constraint for ConstrainedFieldPosition.
     *
     * Constraints are used to control the behavior of iteration in FormattedValue.
     */
    private enum ConstraintType {
        /**
         * Represents the lack of a constraint.
         *
         * This is the value of fConstraint
         * if no "constrain" methods were called.
         */
        NONE,

        /**
         * Represents that the field class is constrained.
         *
         * This is the value of fConstraint
         * after {@link #constrainClass} is called.
         *
         * FormattedValue implementations should not change the field class when this constraint is active.
         */
        CLASS,

        /**
         * Represents that the field is constrained.
         *
         * This is the value of fConstraint
         * after {@link #constrainField} is called.
         *
         * FormattedValue implementations should not change the field when this constraint is active.
         */
        FIELD,

        /**
         * Represents that the field value is constrained.
         *
         * This is the value of fConstraint
         * after {@link #constrainField} is called.
         *
         * FormattedValue implementations should not change the field or value with this constraint.
         */
        VALUE
    };

    private ConstraintType fConstraint;
    private Class<?> fClassConstraint;
    private Field fField;
    private Object fValue;
    private int fStart;
    private int fLimit;
    private long fContext;

    /**
     * Initializes a CategoryFieldPosition.
     *
     * By default, the CategoryFieldPosition has no iteration constraints.
     *
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public ConstrainedFieldPosition() {
        reset();
    }

    /**
     * Resets this ConstrainedFieldPosition to its initial state, as if it were newly created:
     *
     * - Removes any constraints that may have been set on the instance.
     * - Resets the iteration position.
     *
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public void reset() {
        fConstraint = ConstraintType.NONE;
        fClassConstraint = Object.class;
        fField = null;
        fValue = null;
        fStart = 0;
        fLimit = 0;
        fContext = 0;
    }

    /**
     * Sets a constraint on the field.
     *
     * When this instance of ConstrainedFieldPosition is passed to {@link FormattedValue#nextPosition}, positions are
     * skipped unless they have the given field.
     *
     * Any previously set constraints are cleared.
     *
     * For example, to loop over all grouping separators:
     *
     * <pre>
     * ConstrainedFieldPosition cfpos;
     * cfpos.constrainField(NumberFormat.Field.GROUPING_SEPARATOR);
     * while (fmtval.nextPosition(cfpos)) {
     *   // handle the grouping separator position
     * }
     * </pre>
     *
     * Changing the constraint while in the middle of iterating over a FormattedValue
     * does not generally have well-defined behavior.
     *
     * @param field
     *            The field to fix when iterating.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public void constrainField(Field field) {
        if (field == null) {
            throw new IllegalArgumentException("Cannot constrain on null field");
        }
        fConstraint = ConstraintType.FIELD;
        fClassConstraint = Object.class;
        fField = field;
        fValue = null;
    }

    /**
     * Sets a constraint on the field class.
     *
     * When this instance of ConstrainedFieldPosition is passed to {@link FormattedValue#nextPosition}, positions are
     * skipped unless the field is an instance of the class constraint, including subclasses.
     *
     * Any previously set constraints are cleared.
     *
     * For example, to loop over only the number-related fields:
     *
     * <pre>
     * ConstrainedFieldPosition cfpos;
     * cfpos.constrainClass(NumberFormat.Field.class);
     * while (fmtval.nextPosition(cfpos)) {
     *   // handle the number-related field position
     * }
     * </pre>
     *
     * @param classConstraint
     *            The field class to fix when iterating.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public void constrainClass(Class<?> classConstraint) {
        if (classConstraint == null) {
            throw new IllegalArgumentException("Cannot constrain on null field class");
        }
        fConstraint = ConstraintType.CLASS;
        fClassConstraint = classConstraint;
        fField = null;
        fValue = null;
    }

    /**
     * Sets a constraint on field and field value.
     *
     * When this instance of ConstrainedFieldPosition is passed to {@link FormattedValue#nextPosition}, positions are
     * skipped unless both the field and the field value are equal.
     *
     * Any previously set constraints are cleared.
     *
     * For example, to find the span a date interval corresponding to the first date:
     *
     * <pre>
     * ConstrainedFieldPosition cfpos;
     * cfpos.constrainFieldAndValue(DateIntervalFormat.SpanField.DATE_INTERVAL_SPAN, 0);
     * while (fmtval.nextPosition(cfpos)) {
     *   // handle the span of the first date in the date interval
     * }
     * </pre>
     *
     * @param field The field to fix when iterating.
     * @param fieldValue The field value to fix when iterating.
     * @internal ICU 64 Technical Preview
     */
    public void constrainFieldAndValue(Field field, Object fieldValue) {
        fConstraint = ConstraintType.VALUE;
        fClassConstraint = Object.class;
        fField = field;
        fValue = fieldValue;
    }

    /**
     * Gets the field for the current position.
     *
     * The return value is well-defined and non-null only after
     * FormattedValue#nextPosition returns TRUE.
     *
     * @return The field saved in the instance. See above for null conditions.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public Field getField() {
        return fField;
    }

    /**
     * Gets the INCLUSIVE start index for the current position.
     *
     * The return value is well-defined only after FormattedValue#nextPosition returns TRUE.
     *
     * @return The start index saved in the instance.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public int getStart() {
        return fStart;
    }

    /**
     * Gets the EXCLUSIVE end index stored for the current position.
     *
     * The return value is well-defined only after FormattedValue#nextPosition returns TRUE.
     *
     * @return The end index saved in the instance.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public int getLimit() {
        return fLimit;
    }

    /**
     * Gets the value associated with the current field position. The field value is often not set.
     *
     * The return value is well-defined only after FormattedValue#nextPosition returns TRUE.
     *
     * @return The value for the current position. Might be null.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public Object getFieldValue() {
        return fValue;
    }

    /**
     * Gets an int64 that FormattedValue implementations may use for storage.
     *
     * The initial value is zero.
     *
     * Users of FormattedValue should not need to call this method.
     *
     * @return The current iteration context from {@link #setInt64IterationContext}.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public long getInt64IterationContext() {
        return fContext;
    }

    /**
     * Sets an int64 that FormattedValue implementations may use for storage.
     *
     * Intended to be used by FormattedValue implementations.
     *
     * @param context
     *            The new iteration context.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public void setInt64IterationContext(long context) {
        fContext = context;
    }

    /**
     * Sets new values for the primary public getters.
     *
     * Intended to be used by FormattedValue implementations.
     *
     * It is up to the implementation to ensure that the user-requested
     * constraints are satisfied. This method does not check!
     *
     * @param field
     *            The new field.
     * @param value
     *            The new field value. Should be null if there is no value.
     * @param start
     *            The new inclusive start index.
     * @param limit
     *            The new exclusive end index.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public void setState(Field field, Object value, int start, int limit) {
        // Check matchesField only as an assertion (debug build)
        assert matchesField(field, value);

        fField = field;
        fValue = value;
        fStart = start;
        fLimit = limit;
    }

    /**
     * Determines whether a given field and value should be included given the
     * constraints.
     *
     * Intended to be used by FormattedValue implementations.
     *
     * @param field The field to test.
     * @param fieldValue The field value to test. Should be null if there is no value.
     * @return Whether the field should be included given the constraints.
     * @draft ICU 64
     * @provisional This API might change or be removed in a future release.
     */
    public boolean matchesField(Field field, Object fieldValue) {
        if (field == null) {
            throw new IllegalArgumentException("field must not be null");
        }
        switch (fConstraint) {
        case NONE:
            return true;
        case CLASS:
            return fClassConstraint.isAssignableFrom(field.getClass());
        case FIELD:
            return fField == field;
        case VALUE:
            // Note: Objects.equals is Android API level 19 and Java 1.7
            return fField == field && Objects.equals(fValue, fieldValue);
        default:
            throw new AssertionError();
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("CFPos[");
        sb.append(fStart);
        sb.append('-');
        sb.append(fLimit);
        sb.append(' ');
        sb.append(fField);
        sb.append(']');
        return sb.toString();
    }
}
