// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2014-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.io.IOException;
import java.text.Format;

import com.ibm.icu.util.ICUUncheckedIOException;

/**
 * Formats simple patterns like "{1} was born in {0}".
 * Internal version of {@link com.ibm.icu.text.SimpleFormatter}
 * with only static methods, to avoid wrapper objects.
 *
 * <p>This class "compiles" pattern strings into a binary format
 * and implements formatting etc. based on that.
 *
 * <p>Format:
 * Index 0: One more than the highest argument number.
 * Followed by zero or more arguments or literal-text segments.
 *
 * <p>An argument is stored as its number, less than ARG_NUM_LIMIT.
 * A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
 * followed by that many chars.
 */
public final class SimpleFormatterImpl {
    /**
     * Argument numbers must be smaller than this limit.
     * Text segment lengths are offset by this much.
     * This is currently the only unused char value in compiled patterns,
     * except it is the maximum value of the first unit (max arg +1).
     */
    private static final int ARG_NUM_LIMIT = 0x100;
    private static final char LEN1_CHAR = (char)(ARG_NUM_LIMIT + 1);
    private static final char LEN2_CHAR = (char)(ARG_NUM_LIMIT + 2);
    private static final char LEN3_CHAR = (char)(ARG_NUM_LIMIT + 3);
    /**
     * Initial and maximum char/UChar value set for a text segment.
     * Segment length char values are from ARG_NUM_LIMIT+1 to this value here.
     * Normally 0xffff, but can be as small as ARG_NUM_LIMIT+1 for testing.
     */
    private static final char SEGMENT_LENGTH_ARGUMENT_CHAR = (char)0xffff;
    /**
     * Maximum length of a text segment. Longer segments are split into shorter ones.
     */
    private static final int MAX_SEGMENT_LENGTH = SEGMENT_LENGTH_ARGUMENT_CHAR - ARG_NUM_LIMIT;

    /** "Intern" some common patterns. */
    private static final String[][] COMMON_PATTERNS = {
        { "{0} {1}", "\u0002\u0000" + LEN1_CHAR + " \u0001" },
        { "{0} ({1})", "\u0002\u0000" + LEN2_CHAR + " (\u0001" + LEN1_CHAR + ')' },
        { "{0}, {1}", "\u0002\u0000" + LEN2_CHAR + ", \u0001" },
        { "{0} – {1}", "\u0002\u0000" + LEN3_CHAR + " – \u0001" },  // en dash
    };

    /** Use only static methods. */
    private SimpleFormatterImpl() {}

    /**
     * Creates a compiled form of the pattern string, for use with appropriate static methods.
     * The number of arguments checked against the given limits is the
     * highest argument number plus one, not the number of occurrences of arguments.
     *
     * @param pattern The pattern string.
     * @param sb A StringBuilder instance which may or may not be used.
     * @param min The pattern must have at least this many arguments.
     * @param max The pattern must have at most this many arguments.
     * @return The compiled-pattern string.
     * @throws IllegalArgumentException for bad argument syntax and too few or too many arguments.
     */
    public static String compileToStringMinMaxArguments(
            CharSequence pattern, StringBuilder sb, int min, int max) {
        // Return some precompiled common two-argument patterns.
        if (min <= 2 && 2 <= max) {
            for (String[] pair : COMMON_PATTERNS) {
                if (pair[0].contentEquals(pattern)) {
                    assert pair[1].charAt(0) == 2;
                    return pair[1];
                }
            }
        }
        // Parse consistent with MessagePattern, but
        // - support only simple numbered arguments
        // - build a simple binary structure into the result string
        int patternLength = pattern.length();
        sb.ensureCapacity(patternLength);
        // Reserve the first char for the number of arguments.
        sb.setLength(1);
        int textLength = 0;
        int maxArg = -1;
        boolean inQuote = false;
        for (int i = 0; i < patternLength;) {
            char c = pattern.charAt(i++);
            if (c == '\'') {
                if (i < patternLength && (c = pattern.charAt(i)) == '\'') {
                    // double apostrophe, skip the second one
                    ++i;
                } else if (inQuote) {
                    // skip the quote-ending apostrophe
                    inQuote = false;
                    continue;
                } else if (c == '{' || c == '}') {
                    // Skip the quote-starting apostrophe, find the end of the quoted literal text.
                    ++i;
                    inQuote = true;
                } else {
                    // The apostrophe is part of literal text.
                    c = '\'';
                }
            } else if (!inQuote && c == '{') {
                if (textLength > 0) {
                    sb.setCharAt(sb.length() - textLength - 1, (char)(ARG_NUM_LIMIT + textLength));
                    textLength = 0;
                }
                int argNumber;
                if ((i + 1) < patternLength &&
                        0 <= (argNumber = pattern.charAt(i) - '0') && argNumber <= 9 &&
                        pattern.charAt(i + 1) == '}') {
                    i += 2;
                } else {
                    // Multi-digit argument number (no leading zero) or syntax error.
                    // MessagePattern permits PatternProps.skipWhiteSpace(pattern, index)
                    // around the number, but this class does not.
                    int argStart = i - 1;
                    argNumber = -1;
                    if (i < patternLength && '1' <= (c = pattern.charAt(i++)) && c <= '9') {
                        argNumber = c - '0';
                        while (i < patternLength && '0' <= (c = pattern.charAt(i++)) && c <= '9') {
                            argNumber = argNumber * 10 + (c - '0');
                            if (argNumber >= ARG_NUM_LIMIT) {
                                break;
                            }
                        }
                    }
                    if (argNumber < 0 || c != '}') {
                        throw new IllegalArgumentException(
                                "Argument syntax error in pattern \"" + pattern +
                                "\" at index " + argStart +
                                ": " + pattern.subSequence(argStart, i));
                    }
                }
                if (argNumber > maxArg) {
                    maxArg = argNumber;
                }
                sb.append((char)argNumber);
                continue;
            }  // else: c is part of literal text
            // Append c and track the literal-text segment length.
            if (textLength == 0) {
                // Reserve a char for the length of a new text segment, preset the maximum length.
                sb.append(SEGMENT_LENGTH_ARGUMENT_CHAR);
            }
            sb.append(c);
            if (++textLength == MAX_SEGMENT_LENGTH) {
                textLength = 0;
            }
        }
        if (textLength > 0) {
            sb.setCharAt(sb.length() - textLength - 1, (char)(ARG_NUM_LIMIT + textLength));
        }
        int argCount = maxArg + 1;
        if (argCount < min) {
            throw new IllegalArgumentException(
                    "Fewer than minimum " + min + " arguments in pattern \"" + pattern + "\"");
        }
        if (argCount > max) {
            throw new IllegalArgumentException(
                    "More than maximum " + max + " arguments in pattern \"" + pattern + "\"");
        }
        sb.setCharAt(0, (char)argCount);
        return sb.toString();
    }

    /**
     * @param compiledPattern Compiled form of a pattern string.
     * @return The max argument number + 1.
     */
    public static int getArgumentLimit(String compiledPattern) {
        return compiledPattern.charAt(0);
    }

    /**
     * Formats the given values.
     *
     * @param compiledPattern Compiled form of a pattern string.
     */
    public static String formatCompiledPattern(String compiledPattern, CharSequence... values) {
        return formatAndAppend(compiledPattern, new StringBuilder(), null, values).toString();
    }

    /**
     * Formats the not-compiled pattern with the given values.
     * Equivalent to compileToStringMinMaxArguments() followed by formatCompiledPattern().
     * The number of arguments checked against the given limits is the
     * highest argument number plus one, not the number of occurrences of arguments.
     *
     * @param pattern Not-compiled form of a pattern string.
     * @param min The pattern must have at least this many arguments.
     * @param max The pattern must have at most this many arguments.
     * @return The compiled-pattern string.
     * @throws IllegalArgumentException for bad argument syntax and too few or too many arguments.
     */
    public static String formatRawPattern(String pattern, int min, int max, CharSequence... values) {
        StringBuilder sb = new StringBuilder();
        String compiledPattern = compileToStringMinMaxArguments(pattern, sb, min, max);
        sb.setLength(0);
        return formatAndAppend(compiledPattern, sb, null, values).toString();
    }

    /**
     * Formats the given values, appending to the appendTo builder.
     *
     * @param compiledPattern Compiled form of a pattern string.
     * @param appendTo Gets the formatted pattern and values appended.
     * @param offsets offsets[i] receives the offset of where
     *                values[i] replaced pattern argument {i}.
     *                Can be null, or can be shorter or longer than values.
     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
     * @param values The argument values.
     *               An argument value must not be the same object as appendTo.
     *               values.length must be at least getArgumentLimit().
     *               Can be null if getArgumentLimit()==0.
     * @return appendTo
     */
    public static StringBuilder formatAndAppend(
            String compiledPattern, StringBuilder appendTo, int[] offsets, CharSequence... values) {
        int valuesLength = values != null ? values.length : 0;
        if (valuesLength < getArgumentLimit(compiledPattern)) {
            throw new IllegalArgumentException("Too few values.");
        }
        return format(compiledPattern, values, appendTo, null, true, offsets);
    }

    /**
     * Formats the given values, replacing the contents of the result builder.
     * May optimize by actually appending to the result if it is the same object
     * as the value corresponding to the initial argument in the pattern.
     *
     * @param compiledPattern Compiled form of a pattern string.
     * @param result Gets its contents replaced by the formatted pattern and values.
     * @param offsets offsets[i] receives the offset of where
     *                values[i] replaced pattern argument {i}.
     *                Can be null, or can be shorter or longer than values.
     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
     * @param values The argument values.
     *               An argument value may be the same object as result.
     *               values.length must be at least getArgumentLimit().
     * @return result
     */
    public static StringBuilder formatAndReplace(
            String compiledPattern, StringBuilder result, int[] offsets, CharSequence... values) {
        int valuesLength = values != null ? values.length : 0;
        if (valuesLength < getArgumentLimit(compiledPattern)) {
            throw new IllegalArgumentException("Too few values.");
        }

        // If the pattern starts with an argument whose value is the same object
        // as the result, then we keep the result contents and append to it.
        // Otherwise we replace its contents.
        int firstArg = -1;
        // If any non-initial argument value is the same object as the result,
        // then we first copy its contents and use that instead while formatting.
        String resultCopy = null;
        if (getArgumentLimit(compiledPattern) > 0) {
            for (int i = 1; i < compiledPattern.length();) {
                int n = compiledPattern.charAt(i++);
                if (n < ARG_NUM_LIMIT) {
                    if (values[n] == result) {
                        if (i == 2) {
                            firstArg = n;
                        } else if (resultCopy == null) {
                            resultCopy = result.toString();
                        }
                    }
                } else {
                    i += n - ARG_NUM_LIMIT;
                }
            }
        }
        if (firstArg < 0) {
            result.setLength(0);
        }
        return format(compiledPattern, values, result, resultCopy, false, offsets);
    }

    /**
     * Returns the pattern text with none of the arguments.
     * Like formatting with all-empty string values.
     *
     * @param compiledPattern Compiled form of a pattern string.
     */
    public static String getTextWithNoArguments(String compiledPattern) {
        int capacity = compiledPattern.length() - 1 - getArgumentLimit(compiledPattern);
        StringBuilder sb = new StringBuilder(capacity);
        for (int i = 1; i < compiledPattern.length();) {
            int segmentLength = compiledPattern.charAt(i++) - ARG_NUM_LIMIT;
            if (segmentLength > 0) {
                int limit = i + segmentLength;
                sb.append(compiledPattern, i, limit);
                i = limit;
            }
        }
        return sb.toString();
    }

    /**
     * Returns the length of the pattern text with none of the arguments.
     * @param compiledPattern Compiled form of a pattern string.
     * @param codePoints true to count code points; false to count code units.
     * @return The number of code points or code units.
     */
    public static int getLength(String compiledPattern, boolean codePoints) {
        int result = 0;
        for (int i = 1; i < compiledPattern.length();) {
            int segmentLength = compiledPattern.charAt(i++) - ARG_NUM_LIMIT;
            if (segmentLength > 0) {
                int limit = i + segmentLength;
                if (codePoints) {
                    result += Character.codePointCount(compiledPattern, i, limit);
                } else {
                    result += (limit - i);
                }
                i = limit;
            }
        }
        return result;
    }

    /**
     * Returns the length in code units of the pattern text up until the first argument.
     * @param compiledPattern Compiled form of a pattern string.
     * @return The number of code units.
     */
    public static int getPrefixLength(String compiledPattern) {
        if (compiledPattern.length() == 1) {
            return 0;
        } else if (compiledPattern.charAt(0) == 0) {
            return compiledPattern.length() - 2;
        } else if (compiledPattern.charAt(1) <= ARG_NUM_LIMIT) {
            return 0;
        } else {
            return compiledPattern.charAt(1) - ARG_NUM_LIMIT;
        }
    }

    /**
     * Special case for using FormattedStringBuilder with patterns with 0 or 1 argument.
     *
     * With 1 argument, treat the current contents of the FormattedStringBuilder between
     * start and end as the argument {0}. Insert the extra strings from compiledPattern
     * to surround the argument in the output.
     *
     * With 0 arguments, overwrite the entire contents of the FormattedStringBuilder
     * between start and end.
     *
     * @param compiledPattern Compiled form of a pattern string.
     * @param field Field to use when adding chars to the output.
     * @param start The start index of the argument already in the output string.
     * @param end The end index of the argument already in the output string.
     * @param output Destination for formatted output.
     * @return Net number of characters added to the formatted string.
     */
    public static int formatPrefixSuffix(
            String compiledPattern,
            Format.Field field,
            int start,
            int end,
            FormattedStringBuilder output) {
        int argLimit = getArgumentLimit(compiledPattern);
        if (argLimit == 0) {
            // No arguments in compiled pattern; overwrite the entire segment with our string.
            return output.splice(start, end, compiledPattern, 2, compiledPattern.length(), field);
        } else {
            assert argLimit == 1;
            int suffixOffset;
            int length = 0;
            if (compiledPattern.charAt(1) != '\u0000') {
                int prefixLength = compiledPattern.charAt(1) - ARG_NUM_LIMIT;
                length = output.insert(start, compiledPattern, 2, 2 + prefixLength, field);
                suffixOffset = 3 + prefixLength;
            } else {
                suffixOffset = 2;
            }
            if (suffixOffset < compiledPattern.length()) {
                int suffixLength = compiledPattern.charAt(suffixOffset) - ARG_NUM_LIMIT;
                length += output.insert(end + length, compiledPattern, 1 + suffixOffset,
                        1 + suffixOffset + suffixLength, field);
            }
            return length;
        }
    }

    /** Internal iterator interface for maximum efficiency.
     *
     * Usage boilerplate:
     *
     * <pre>
     * long state = 0;
     * while (true) {
     *     state = IterInternal.step(state, compiledPattern, output);
     *     if (state == IterInternal.DONE) {
     *         break;
     *     }
     *     int argIndex = IterInternal.getArgIndex(state);
     *     // Append the string corresponding to argIndex to output
     * }
     * </pre>
     *
     */
    public static class IterInternal {
        public static final long DONE = -1;

        public static long step(long state, CharSequence compiledPattern, Appendable output) {
            int i = (int) (state >>> 32);
            assert i < compiledPattern.length();
            i++;
            while (i < compiledPattern.length() && compiledPattern.charAt(i) > ARG_NUM_LIMIT) {
                int limit = i + compiledPattern.charAt(i) + 1 - ARG_NUM_LIMIT;
                try {
                    output.append(compiledPattern, i + 1, limit);
                } catch (IOException e) {
                    throw new ICUUncheckedIOException(e);
                }
                i = limit;
            }
            if (i == compiledPattern.length()) {
                return DONE;
            }
            return (((long) i) << 32) | compiledPattern.charAt(i);
        }

        public static int getArgIndex(long state) {
            return (int) state;
        }
    }

    private static StringBuilder format(
            String compiledPattern, CharSequence[] values,
            StringBuilder result, String resultCopy, boolean forbidResultAsValue,
            int[] offsets) {
        int offsetsLength;
        if (offsets == null) {
            offsetsLength = 0;
        } else {
            offsetsLength = offsets.length;
            for (int i = 0; i < offsetsLength; i++) {
                offsets[i] = -1;
            }
        }
        for (int i = 1; i < compiledPattern.length();) {
            int n = compiledPattern.charAt(i++);
            if (n < ARG_NUM_LIMIT) {
                CharSequence value = values[n];
                if (value == result) {
                    if (forbidResultAsValue) {
                        throw new IllegalArgumentException("Value must not be same object as result");
                    }
                    if (i == 2) {
                        // We are appending to result which is also the first value object.
                        if (n < offsetsLength) {
                            offsets[n] = 0;
                        }
                    } else {
                        if (n < offsetsLength) {
                            offsets[n] = result.length();
                        }
                        result.append(resultCopy);
                    }
                } else {
                    if (n < offsetsLength) {
                        offsets[n] = result.length();
                    }
                    result.append(value);
                }
            } else {
                int limit = i + (n - ARG_NUM_LIMIT);
                result.append(compiledPattern, i, limit);
                i = limit;
            }
        }
        return result;
    }
}
