// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
 * COPYRIGHT:
 * Copyright (c) 2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

#include "datadrivennumberformattestsuite.h"

#if !UCONFIG_NO_FORMATTING

#include "charstr.h"
#include "ucbuf.h"
#include "unicode/localpointer.h"
#include "ustrfmt.h"

static UBool isCROrLF(UChar c) { return c == 0xa || c == 0xd; }
static UBool isSpace(UChar c) { return c == 9 || c == 0x20 || c == 0x3000; }

void DataDrivenNumberFormatTestSuite::run(const char *fileName, UBool runAllTests) {
    fFileLineNumber = 0;
    fFormatTestNumber = 0;
    UErrorCode status = U_ZERO_ERROR;
    for (int32_t i = 0; i < UPRV_LENGTHOF(fPreviousFormatters); ++i) {
        delete fPreviousFormatters[i];
        fPreviousFormatters[i] = newFormatter(status);
    }
    if (!assertSuccess("Can't create previous formatters", status)) {
        return;
    }
    CharString path(getSourceTestData(status), status);
    path.appendPathPart(fileName, status);
    const char *codePage = "UTF-8";
    LocalUCHARBUFPointer f(ucbuf_open(path.data(), &codePage, TRUE, FALSE, &status));
    if (!assertSuccess("Can't open data file", status)) {
        return;
    }
    UnicodeString columnValues[kNumberFormatTestTupleFieldCount];
    ENumberFormatTestTupleField columnTypes[kNumberFormatTestTupleFieldCount];
    int32_t columnCount = 0;
    int32_t state = 0;
    while(U_SUCCESS(status)) {
        // Read a new line if necessary.
        if(fFileLine.isEmpty()) {
            if(!readLine(f.getAlias(), status)) { break; }
            if (fFileLine.isEmpty() && state == 2) {
                state = 0;
            }
            continue;
        }
        if (fFileLine.startsWith("//")) {
            fFileLine.remove();
            continue;
        }
        // Initial setup of test.
        if (state == 0) {
            if (fFileLine.startsWith(UNICODE_STRING("test ", 5))) {
                fFileTestName = fFileLine;
                fTuple.clear();
            } else if(fFileLine.startsWith(UNICODE_STRING("set ", 4))) {
                setTupleField(status);
            } else if(fFileLine.startsWith(UNICODE_STRING("begin", 5))) {
                state = 1;
            } else {
                showError("Unrecognized verb.");
                return;
            }
        // column specification
        } else if (state == 1) {
            columnCount = splitBy(columnValues, UPRV_LENGTHOF(columnValues), 0x9);
            for (int32_t i = 0; i < columnCount; ++i) {
                columnTypes[i] = NumberFormatTestTuple::getFieldByName(
                    columnValues[i]);
                if (columnTypes[i] == kNumberFormatTestTupleFieldCount) {
                    showError("Unrecognized field name.");
                    return;
                }
            }
            state = 2;
        // run the tests
        } else {
            int32_t columnsInThisRow = splitBy(columnValues, columnCount, 0x9);
            for (int32_t i = 0; i < columnsInThisRow; ++i) {
                fTuple.setField(
                        columnTypes[i], columnValues[i].unescape(), status);
            }
            for (int32_t i = columnsInThisRow; i < columnCount; ++i) {
                fTuple.clearField(columnTypes[i], status);
            }
            if (U_FAILURE(status)) {
                showError("Invalid column values");
                return;
            }
            if (runAllTests || !breaksC()) {
                UnicodeString errorMessage;
                UBool shouldFail = (NFTT_GET_FIELD(fTuple, output, "") == "fail")
                        ? !breaksC()
                        : breaksC();
                UBool actualSuccess = isPass(fTuple, errorMessage, status);
                if (shouldFail && actualSuccess) {
                    showFailure("Expected failure, but passed: " + errorMessage);
                    break;
                } else if (!shouldFail && !actualSuccess) {
                    showFailure(errorMessage);
                    break;
                }
                status = U_ZERO_ERROR;
            }
        }
        fFileLine.remove();
    }
}

DataDrivenNumberFormatTestSuite::~DataDrivenNumberFormatTestSuite() {
    for (int32_t i = 0; i < UPRV_LENGTHOF(fPreviousFormatters); ++i) {
        delete fPreviousFormatters[i];
    }
}

UBool DataDrivenNumberFormatTestSuite::breaksC() {
    return (NFTT_GET_FIELD(fTuple, breaks, "").toUpper().indexOf((UChar)0x43) != -1);
}

void DataDrivenNumberFormatTestSuite::setTupleField(UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    UnicodeString parts[3];
    int32_t partCount = splitBy(parts, UPRV_LENGTHOF(parts), 0x20);
    if (partCount < 3) {
        showError("Set expects 2 parameters");
        status = U_PARSE_ERROR;
        return;
    }
    if (!fTuple.setField(
            NumberFormatTestTuple::getFieldByName(parts[1]),
            parts[2].unescape(),
            status)) {
        showError("Invalid field value");
    }
}


int32_t
DataDrivenNumberFormatTestSuite::splitBy(
        UnicodeString *columnValues,
        int32_t columnValuesCount,
        UChar delimiter) {
    int32_t colIdx = 0;
    int32_t colStart = 0;
    int32_t len = fFileLine.length();
    for (int32_t idx = 0; colIdx < columnValuesCount - 1 && idx < len; ++idx) {
        UChar ch = fFileLine.charAt(idx);
        if (ch == delimiter) {
            columnValues[colIdx++] = 
                    fFileLine.tempSubString(colStart, idx - colStart);
            colStart = idx + 1;
        }
    }
    columnValues[colIdx++] = 
            fFileLine.tempSubString(colStart, len - colStart);
    return colIdx;
}

void DataDrivenNumberFormatTestSuite::showLineInfo() {
    UnicodeString indent("    ");
    infoln(indent + fFileTestName);
    infoln(indent + fFileLine);
}

void DataDrivenNumberFormatTestSuite::showError(const char *message) {
    errln("line %d: %s", (int) fFileLineNumber, message);
    showLineInfo();
}

void DataDrivenNumberFormatTestSuite::showFailure(const UnicodeString &message) {
    UChar lineStr[20];
    uprv_itou(
            lineStr, UPRV_LENGTHOF(lineStr), (uint32_t) fFileLineNumber, 10, 1);
    UnicodeString fullMessage("line ");
    dataerrln(fullMessage.append(lineStr).append(": ")
            .append(prettify(message)));
    showLineInfo();
}

UBool DataDrivenNumberFormatTestSuite::readLine(
        UCHARBUF *f, UErrorCode &status) {
    int32_t lineLength;
    const UChar *line = ucbuf_readline(f, &lineLength, &status);
    if(line == NULL || U_FAILURE(status)) {
        if (U_FAILURE(status)) {
            errln("Error reading line from file.");
        }
        fFileLine.remove();
        return FALSE;
    }
    ++fFileLineNumber;
    // Strip trailing CR/LF, comments, and spaces.
    while(lineLength > 0 && isCROrLF(line[lineLength - 1])) { --lineLength; }
    fFileLine.setTo(FALSE, line, lineLength);
    while(lineLength > 0 && isSpace(line[lineLength - 1])) { --lineLength; }
    if (lineLength == 0) {
        fFileLine.remove();
    }
    return TRUE;
}

UBool DataDrivenNumberFormatTestSuite::isPass(
        const NumberFormatTestTuple &tuple,
        UnicodeString &appendErrorMessage,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    UBool result = FALSE;
    if (tuple.formatFlag && tuple.outputFlag) {
        ++fFormatTestNumber;
        result = isFormatPass(
                tuple,
                fPreviousFormatters[
                        fFormatTestNumber % UPRV_LENGTHOF(fPreviousFormatters)],
                appendErrorMessage,
                status);
    }
    else if (tuple.toPatternFlag || tuple.toLocalizedPatternFlag) {
        result = isToPatternPass(tuple, appendErrorMessage, status);
    } else if (tuple.parseFlag && tuple.outputFlag && tuple.outputCurrencyFlag) {
        result = isParseCurrencyPass(tuple, appendErrorMessage, status);

    } else if (tuple.parseFlag && tuple.outputFlag) {
        result = isParsePass(tuple, appendErrorMessage, status);
    } else if (tuple.pluralFlag) {
        result = isSelectPass(tuple, appendErrorMessage, status);
    } else {
        appendErrorMessage.append("Unrecognized test type.");
        status = U_ILLEGAL_ARGUMENT_ERROR;
    }
    if (!result) {
        if (appendErrorMessage.length() > 0) {
            appendErrorMessage.append(": ");
        }
        if (U_FAILURE(status)) {
            appendErrorMessage.append(u_errorName(status));
            appendErrorMessage.append(": ");
        }
        tuple.toString(appendErrorMessage);
    }
    return result;
}

UBool DataDrivenNumberFormatTestSuite::isFormatPass(
        const NumberFormatTestTuple & /* tuple */,
        UnicodeString & /*appendErrorMessage*/,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return TRUE;
}
    
UBool DataDrivenNumberFormatTestSuite::isFormatPass(
        const NumberFormatTestTuple &tuple,
        UObject * /* somePreviousFormatter */,
        UnicodeString &appendErrorMessage,
        UErrorCode &status) {
    return isFormatPass(tuple, appendErrorMessage, status);
}

UObject *DataDrivenNumberFormatTestSuite::newFormatter(
        UErrorCode & /*status*/) {
    return NULL;
}

UBool DataDrivenNumberFormatTestSuite::isToPatternPass(
        const NumberFormatTestTuple & /* tuple */,
        UnicodeString & /*appendErrorMessage*/,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return TRUE;
}

UBool DataDrivenNumberFormatTestSuite::isParsePass(
        const NumberFormatTestTuple & /* tuple */,
        UnicodeString & /*appendErrorMessage*/,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return TRUE;
}

UBool DataDrivenNumberFormatTestSuite::isParseCurrencyPass(
        const NumberFormatTestTuple & /* tuple */,
        UnicodeString & /*appendErrorMessage*/,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return TRUE;
}

UBool DataDrivenNumberFormatTestSuite::isSelectPass(
        const NumberFormatTestTuple & /* tuple */,
        UnicodeString & /*appendErrorMessage*/,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    return TRUE;
}
#endif /* !UCONFIG_NO_FORMATTING */
