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

import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.FieldPosition;
import java.text.Format.Field;

import com.ibm.icu.text.ConstrainedFieldPosition;
import com.ibm.icu.text.ListFormatter;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.UFormat;
import com.ibm.icu.text.UnicodeSet;

/**
 * Implementation of FormattedValue based on FormattedStringBuilder.
 *
 * The implementation currently revolves around numbers and number fields.
 * However, it can be generalized in the future when there is a need.
 *
 * In C++, this implements FormattedValue. In Java, it is a stateless
 * collection of static functions to avoid having to use nested objects.
 *
 * @author sffc (Shane Carr)
 */
public class FormattedValueStringBuilderImpl {

    /**
     * Placeholder field used for calculating spans.
     * Does not currently support nested fields beyond one level.
     */
    public static class SpanFieldPlaceholder {
        public UFormat.SpanField spanField;
        public Field normalField;
        public Object value;
    }

    /**
     * Finds the index at which a span field begins.
     *
     * @param value The value of the span field to search for.
     * @return The index, or -1 if not found.
     */
    public static int findSpan(FormattedStringBuilder self, Object value) {
        for (int i = self.zero; i < self.zero + self.length; i++) {
            if (!(self.fields[i] instanceof SpanFieldPlaceholder)) {
                continue;
            }
            if (((SpanFieldPlaceholder) self.fields[i]).value.equals(value)) {
                return i - self.zero;
            }
        }
        return -1;
    }

    public static boolean nextFieldPosition(FormattedStringBuilder self, FieldPosition fp) {
        java.text.Format.Field rawField = fp.getFieldAttribute();

        if (rawField == null) {
            // Backwards compatibility: read from fp.getField()
            if (fp.getField() == NumberFormat.INTEGER_FIELD) {
                rawField = NumberFormat.Field.INTEGER;
            } else if (fp.getField() == NumberFormat.FRACTION_FIELD) {
                rawField = NumberFormat.Field.FRACTION;
            } else {
                // No field is set
                return false;
            }
        }

        if (!(rawField instanceof NumberFormat.Field)) {
            throw new IllegalArgumentException(
                    "You must pass an instance of com.ibm.icu.text.NumberFormat.Field as your FieldPosition attribute.  You passed: "
                            + rawField.getClass().toString());
        }

        ConstrainedFieldPosition cfpos = new ConstrainedFieldPosition();
        cfpos.constrainField(rawField);
        cfpos.setState(rawField, null, fp.getBeginIndex(), fp.getEndIndex());
        if (nextPosition(self, cfpos, null)) {
            fp.setBeginIndex(cfpos.getStart());
            fp.setEndIndex(cfpos.getLimit());
            return true;
        }

        // Special case: fraction should start after integer if fraction is not present
        if (rawField == NumberFormat.Field.FRACTION && fp.getEndIndex() == 0) {
            boolean inside = false;
            int i = self.zero;
            for (; i < self.zero + self.length; i++) {
                if (isIntOrGroup(self.fields[i]) || self.fields[i] == NumberFormat.Field.DECIMAL_SEPARATOR) {
                    inside = true;
                } else if (inside) {
                    break;
                }
            }
            fp.setBeginIndex(i - self.zero);
            fp.setEndIndex(i - self.zero);
        }

        return false;
    }

    public static AttributedCharacterIterator toCharacterIterator(FormattedStringBuilder self, Field numericField) {
        ConstrainedFieldPosition cfpos = new ConstrainedFieldPosition();
        AttributedString as = new AttributedString(self.toString());
        while (nextPosition(self, cfpos, numericField)) {
            // Backwards compatibility: field value = field
            Object value = cfpos.getFieldValue();
            if (value == null) {
                value = cfpos.getField();
            }
            as.addAttribute(cfpos.getField(), value, cfpos.getStart(), cfpos.getLimit());
        }
        return as.getIterator();
    }

    static class NullField extends Field {
        private static final long serialVersionUID = 1L;
        static final NullField END = new NullField("end");
        private NullField(String name) {
            super(name);
        }
    }

    /**
     * Implementation of nextPosition consistent with the contract of FormattedValue.
     *
     * @param cfpos
     *            The argument passed to the public API.
     * @param numericField
     *            Optional. If non-null, apply this field to the entire numeric portion of the string.
     * @return See FormattedValue#nextPosition.
     */
    public static boolean nextPosition(FormattedStringBuilder self, ConstrainedFieldPosition cfpos, Field numericField) {
        int fieldStart = -1;
        Object currField = null;
        for (int i = self.zero + cfpos.getLimit(); i <= self.zero + self.length; i++) {
            Object _field = (i < self.zero + self.length) ? self.fields[i] : NullField.END;
            // Case 1: currently scanning a field.
            if (currField != null) {
                if (currField != _field) {
                    int end = i - self.zero;
                    // Handle span fields; don't trim them
                    if (currField instanceof SpanFieldPlaceholder) {
                        assert handleSpan(currField, cfpos, fieldStart, end);
                        return true;
                    }
                    // Grouping separators can be whitespace; don't throw them out!
                    if (isTrimmable(currField)) {
                        end = trimBack(self, end);
                    }
                    if (end <= fieldStart) {
                        // Entire field position is ignorable; skip.
                        fieldStart = -1;
                        currField = null;
                        i--;  // look at this index again
                        continue;
                    }
                    int start = fieldStart;
                    if (isTrimmable(currField)) {
                        start = trimFront(self, start);
                    }
                    cfpos.setState((Field) currField, null, start, end);
                    return true;
                }
                continue;
            }
            // Special case: coalesce the INTEGER if we are pointing at the end of the INTEGER.
            if (cfpos.matchesField(NumberFormat.Field.INTEGER, null)
                    && i > self.zero
                    // don't return the same field twice in a row:
                    && i - self.zero > cfpos.getLimit()
                    && isIntOrGroup(self.fields[i - 1])
                    && !isIntOrGroup(_field)) {
                int j = i - 1;
                for (; j >= self.zero && isIntOrGroup(self.fields[j]); j--) {}
                cfpos.setState(NumberFormat.Field.INTEGER, null, j - self.zero + 1, i - self.zero);
                return true;
            }
            // Special case: coalesce NUMERIC if we are pointing at the end of the NUMERIC.
            if (numericField != null
                    && cfpos.matchesField(numericField, null)
                    && i > self.zero
                    // don't return the same field twice in a row:
                    && (i - self.zero > cfpos.getLimit() || cfpos.getField() != numericField)
                    && isNumericField(self.fields[i - 1])
                    && !isNumericField(_field)) {
                int j = i - 1;
                for (; j >= self.zero && isNumericField(self.fields[j]); j--) {}
                cfpos.setState(numericField, null, j - self.zero + 1, i - self.zero);
                return true;
            }
            // Special case: emit normalField if we are pointing at the end of spanField.
            if (i > self.zero
                    && self.fields[i-1] instanceof SpanFieldPlaceholder) {
                int j = i - 1;
                for (; j >= self.zero && self.fields[j] == self.fields[i-1]; j--) {}
                if (handleSpan(self.fields[i-1], cfpos, j - self.zero + 1, i - self.zero)) {
                    return true;
                }
            }
            // Special case: skip over INTEGER; will be coalesced later.
            if (_field == NumberFormat.Field.INTEGER) {
                _field = null;
            }
            // Case 2: no field starting at this position.
            if (_field == null || _field == NullField.END) {
                continue;
            }
            // Case 3: check for field starting at this position
            // Case 3a: SpanField placeholder
            if (_field instanceof SpanFieldPlaceholder) {
                SpanFieldPlaceholder ph = (SpanFieldPlaceholder) _field;
                if (cfpos.matchesField(ph.normalField, null) || cfpos.matchesField(ph.spanField, ph.value)) {
                    fieldStart = i - self.zero;
                    currField = _field;
                }
            }
            // Case 3b: No SpanField
            else if (cfpos.matchesField((Field) _field, null)) {
                fieldStart = i - self.zero;
                currField = _field;
            }
        }

        assert currField == null;
        return false;
    }

    private static boolean isIntOrGroup(Object field) {
        return field == NumberFormat.Field.INTEGER || field == NumberFormat.Field.GROUPING_SEPARATOR;
    }

    private static boolean isNumericField(Object field) {
        return field == null || NumberFormat.Field.class.isAssignableFrom(field.getClass());
    }

    private static boolean isTrimmable(Object field) {
        return field != NumberFormat.Field.GROUPING_SEPARATOR
                && !(field instanceof ListFormatter.Field);
    }

    private static int trimBack(FormattedStringBuilder self, int limit) {
        return StaticUnicodeSets.get(StaticUnicodeSets.Key.DEFAULT_IGNORABLES)
                .spanBack(self, limit, UnicodeSet.SpanCondition.CONTAINED);
    }

    private static int trimFront(FormattedStringBuilder self, int start) {
        return StaticUnicodeSets.get(StaticUnicodeSets.Key.DEFAULT_IGNORABLES)
                .span(self, start, UnicodeSet.SpanCondition.CONTAINED);
    }

    private static boolean handleSpan(Object field, ConstrainedFieldPosition cfpos, int start, int limit) {
        SpanFieldPlaceholder ph = (SpanFieldPlaceholder) field;
        if (cfpos.matchesField(ph.spanField, ph.value)
                && cfpos.getLimit() < limit) {
            cfpos.setState(ph.spanField, ph.value, start, limit);
            return true;
        }
        if (cfpos.matchesField(ph.normalField, null)
                && (cfpos.getLimit() < limit || cfpos.getField() != ph.normalField)) {
            cfpos.setState(ph.normalField, null, start, limit);
            return true;
        }
        return false;
    }
}
