// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
******************************************************************************
* Copyright (C) 2014-2016, International Business Machines
* Corporation and others.  All Rights Reserved.
******************************************************************************
* simpleformatter.cpp
*/

#include "unicode/utypes.h"
#include "unicode/simpleformatter.h"
#include "unicode/unistr.h"
#include "uassert.h"

U_NAMESPACE_BEGIN

namespace {

/**
 * 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).
 */
const int32_t ARG_NUM_LIMIT = 0x100;
/**
 * 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.
 */
const UChar SEGMENT_LENGTH_PLACEHOLDER_CHAR = 0xffff;
/**
 * Maximum length of a text segment. Longer segments are split into shorter ones.
 */
const int32_t MAX_SEGMENT_LENGTH = SEGMENT_LENGTH_PLACEHOLDER_CHAR - ARG_NUM_LIMIT;

enum {
    APOS = 0x27,
    DIGIT_ZERO = 0x30,
    DIGIT_ONE = 0x31,
    DIGIT_NINE = 0x39,
    OPEN_BRACE = 0x7b,
    CLOSE_BRACE = 0x7d
};

inline UBool isInvalidArray(const void *array, int32_t length) {
   return (length < 0 || (array == NULL && length != 0));
}

}  // namespace

SimpleFormatter &SimpleFormatter::operator=(const SimpleFormatter& other) {
    if (this == &other) {
        return *this;
    }
    compiledPattern = other.compiledPattern;
    return *this;
}

SimpleFormatter::~SimpleFormatter() {}

UBool SimpleFormatter::applyPatternMinMaxArguments(
        const UnicodeString &pattern,
        int32_t min, int32_t max,
        UErrorCode &errorCode) {
    if (U_FAILURE(errorCode)) {
        return FALSE;
    }
    // Parse consistent with MessagePattern, but
    // - support only simple numbered arguments
    // - build a simple binary structure into the result string
    const UChar *patternBuffer = pattern.getBuffer();
    int32_t patternLength = pattern.length();
    // Reserve the first char for the number of arguments.
    compiledPattern.setTo((UChar)0);
    int32_t textLength = 0;
    int32_t maxArg = -1;
    UBool inQuote = FALSE;
    for (int32_t i = 0; i < patternLength;) {
        UChar c = patternBuffer[i++];
        if (c == APOS) {
            if (i < patternLength && (c = patternBuffer[i]) == APOS) {
                // double apostrophe, skip the second one
                ++i;
            } else if (inQuote) {
                // skip the quote-ending apostrophe
                inQuote = FALSE;
                continue;
            } else if (c == OPEN_BRACE || c == CLOSE_BRACE) {
                // 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 = APOS;
            }
        } else if (!inQuote && c == OPEN_BRACE) {
            if (textLength > 0) {
                compiledPattern.setCharAt(compiledPattern.length() - textLength - 1,
                                          (UChar)(ARG_NUM_LIMIT + textLength));
                textLength = 0;
            }
            int32_t argNumber;
            if ((i + 1) < patternLength &&
                    0 <= (argNumber = patternBuffer[i] - DIGIT_ZERO) && argNumber <= 9 &&
                    patternBuffer[i + 1] == CLOSE_BRACE) {
                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.
                argNumber = -1;
                if (i < patternLength && DIGIT_ONE <= (c = patternBuffer[i++]) && c <= DIGIT_NINE) {
                    argNumber = c - DIGIT_ZERO;
                    while (i < patternLength &&
                            DIGIT_ZERO <= (c = patternBuffer[i++]) && c <= DIGIT_NINE) {
                        argNumber = argNumber * 10 + (c - DIGIT_ZERO);
                        if (argNumber >= ARG_NUM_LIMIT) {
                            break;
                        }
                    }
                }
                if (argNumber < 0 || c != CLOSE_BRACE) {
                    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
                    return FALSE;
                }
            }
            if (argNumber > maxArg) {
                maxArg = argNumber;
            }
            compiledPattern.append((UChar)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.
            compiledPattern.append(SEGMENT_LENGTH_PLACEHOLDER_CHAR);
        }
        compiledPattern.append(c);
        if (++textLength == MAX_SEGMENT_LENGTH) {
            textLength = 0;
        }
    }
    if (textLength > 0) {
        compiledPattern.setCharAt(compiledPattern.length() - textLength - 1,
                                  (UChar)(ARG_NUM_LIMIT + textLength));
    }
    int32_t argCount = maxArg + 1;
    if (argCount < min || max < argCount) {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return FALSE;
    }
    compiledPattern.setCharAt(0, (UChar)argCount);
    return TRUE;
}

UnicodeString& SimpleFormatter::format(
        const UnicodeString &value0,
        UnicodeString &appendTo, UErrorCode &errorCode) const {
    const UnicodeString *values[] = { &value0 };
    return formatAndAppend(values, 1, appendTo, NULL, 0, errorCode);
}

UnicodeString& SimpleFormatter::format(
        const UnicodeString &value0,
        const UnicodeString &value1,
        UnicodeString &appendTo, UErrorCode &errorCode) const {
    const UnicodeString *values[] = { &value0, &value1 };
    return formatAndAppend(values, 2, appendTo, NULL, 0, errorCode);
}

UnicodeString& SimpleFormatter::format(
        const UnicodeString &value0,
        const UnicodeString &value1,
        const UnicodeString &value2,
        UnicodeString &appendTo, UErrorCode &errorCode) const {
    const UnicodeString *values[] = { &value0, &value1, &value2 };
    return formatAndAppend(values, 3, appendTo, NULL, 0, errorCode);
}

UnicodeString& SimpleFormatter::formatAndAppend(
        const UnicodeString *const *values, int32_t valuesLength,
        UnicodeString &appendTo,
        int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const {
    if (U_FAILURE(errorCode)) {
        return appendTo;
    }
    if (isInvalidArray(values, valuesLength) || isInvalidArray(offsets, offsetsLength) ||
            valuesLength < getArgumentLimit()) {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }
    return format(compiledPattern.getBuffer(), compiledPattern.length(), values,
                  appendTo, NULL, TRUE,
                  offsets, offsetsLength, errorCode);
}

UnicodeString &SimpleFormatter::formatAndReplace(
        const UnicodeString *const *values, int32_t valuesLength,
        UnicodeString &result,
        int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const {
    if (U_FAILURE(errorCode)) {
        return result;
    }
    if (isInvalidArray(values, valuesLength) || isInvalidArray(offsets, offsetsLength)) {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }
    const UChar *cp = compiledPattern.getBuffer();
    int32_t cpLength = compiledPattern.length();
    if (valuesLength < getArgumentLimit(cp, cpLength)) {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }

    // 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.
    int32_t 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.
    UnicodeString resultCopy;
    if (getArgumentLimit(cp, cpLength) > 0) {
        for (int32_t i = 1; i < cpLength;) {
            int32_t n = cp[i++];
            if (n < ARG_NUM_LIMIT) {
                if (values[n] == &result) {
                    if (i == 2) {
                        firstArg = n;
                    } else if (resultCopy.isEmpty() && !result.isEmpty()) {
                        resultCopy = result;
                    }
                }
            } else {
                i += n - ARG_NUM_LIMIT;
            }
        }
    }
    if (firstArg < 0) {
        result.remove();
    }
    return format(cp, cpLength, values,
                  result, &resultCopy, FALSE,
                  offsets, offsetsLength, errorCode);
}

UnicodeString SimpleFormatter::getTextWithNoArguments(
        const UChar *compiledPattern, int32_t compiledPatternLength) {
    int32_t capacity = compiledPatternLength - 1 -
            getArgumentLimit(compiledPattern, compiledPatternLength);
    UnicodeString sb(capacity, 0, 0);  // Java: StringBuilder
    for (int32_t i = 1; i < compiledPatternLength;) {
        int32_t segmentLength = compiledPattern[i++] - ARG_NUM_LIMIT;
        if (segmentLength > 0) {
            sb.append(compiledPattern + i, segmentLength);
            i += segmentLength;
        }
    }
    return sb;
}

UnicodeString &SimpleFormatter::format(
        const UChar *compiledPattern, int32_t compiledPatternLength,
        const UnicodeString *const *values,
        UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue,
        int32_t *offsets, int32_t offsetsLength,
        UErrorCode &errorCode) {
    if (U_FAILURE(errorCode)) {
        return result;
    }
    for (int32_t i = 0; i < offsetsLength; i++) {
        offsets[i] = -1;
    }
    for (int32_t i = 1; i < compiledPatternLength;) {
        int32_t n = compiledPattern[i++];
        if (n < ARG_NUM_LIMIT) {
            const UnicodeString *value = values[n];
            if (value == NULL) {
                errorCode = U_ILLEGAL_ARGUMENT_ERROR;
                return result;
            }
            if (value == &result) {
                if (forbidResultAsValue) {
                    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
                    return 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 {
            int32_t length = n - ARG_NUM_LIMIT;
            result.append(compiledPattern + i, length);
            i += length;
        }
    }
    return result;
}

U_NAMESPACE_END
