/*
 *******************************************************************************
 * Copyright (C) 2014-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.text;

import com.ibm.icu.impl.SimpleFormatterImpl;

/**
 * Formats simple patterns like "{1} was born in {0}".
 * Minimal subset of MessageFormat; fast, simple, minimal dependencies.
 * Supports only numbered arguments with no type nor style parameters,
 * and formats only string values.
 * Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
 *
 * <p>Factory methods throw exceptions for syntax errors
 * and for too few or too many arguments/placeholders.
 *
 * <p>SimpleFormatter objects are immutable and can be safely cached like strings.
 *
 * <p>Example:
 * <pre>
 * SimpleFormatter fmt = SimpleFormatter.compile("{1} '{born}' in {0}");
 *
 * // Output: "paul {born} in england"
 * System.out.println(fmt.format("england", "paul"));
 * </pre>
 *
 * @see MessageFormat
 * @see MessagePattern.ApostropheMode
 * @draft ICU 57
 * @provisional This API might change or be removed in a future release.
 */
public final class SimpleFormatter {
    // For internal use in Java, use SimpleFormatterImpl directly instead:
    // It is most efficient to compile patterns to compiled-pattern strings
    // and use them with static methods.
    // (Avoids allocating SimpleFormatter wrapper objects.)

    /**
     * Binary representation of the compiled pattern.
     * @see SimpleFormatterImpl
     */
    private final String compiledPattern;

    private SimpleFormatter(String compiledPattern) {
        this.compiledPattern = compiledPattern;
    }

    /**
     * Creates a formatter from the pattern string.
     *
     * @param pattern The pattern string.
     * @return The new SimpleFormatter object.
     * @throws IllegalArgumentException for bad argument syntax.
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    public static SimpleFormatter compile(CharSequence pattern) {
        return compileMinMaxArguments(pattern, 0, Integer.MAX_VALUE);
    }

    /**
     * Creates a formatter from the pattern string.
     * 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 min The pattern must have at least this many arguments.
     * @param max The pattern must have at most this many arguments.
     * @return The new SimpleFormatter object.
     * @throws IllegalArgumentException for bad argument syntax and too few or too many arguments.
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    public static SimpleFormatter compileMinMaxArguments(CharSequence pattern, int min, int max) {
        StringBuilder sb = new StringBuilder();
        String compiledPattern = SimpleFormatterImpl.compileToStringMinMaxArguments(pattern, sb, min, max);
        return new SimpleFormatter(compiledPattern);
    }

    /**
     * @return The max argument number + 1.
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    public int getArgumentLimit() {
        return SimpleFormatterImpl.getArgumentLimit(compiledPattern);
    }

    /**
     * Formats the given values.
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    public String format(CharSequence... values) {
        return SimpleFormatterImpl.formatCompiledPattern(compiledPattern, values);
    }

    /**
     * Formats the given values, appending to the appendTo builder.
     *
     * @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
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    public StringBuilder formatAndAppend(
            StringBuilder appendTo, int[] offsets, CharSequence... values) {
        return SimpleFormatterImpl.formatAndAppend(compiledPattern, appendTo, offsets, values);
    }

    /**
     * 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 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
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    public StringBuilder formatAndReplace(
            StringBuilder result, int[] offsets, CharSequence... values) {
        return SimpleFormatterImpl.formatAndReplace(compiledPattern, result, offsets, values);
    }

    /**
     * Returns a string similar to the original pattern, only for debugging.
     *
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    @Override
    public String toString() {
        String[] values = new String[getArgumentLimit()];
        for (int i = 0; i < values.length; i++) {
            values[i] = "{" + i + '}';
        }
        return formatAndAppend(new StringBuilder(), null, values).toString();
    }

    /**
     * Returns the pattern text with none of the arguments.
     * Like formatting with all-empty string values.
     *
     * @draft ICU 57
     * @provisional This API might change or be removed in a future release.
     */
    public String getTextWithNoArguments() {
        return SimpleFormatterImpl.getTextWithNoArguments(compiledPattern);
    }
}
