// Copyright (C) 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;
    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 (!breaksC() || runAllTests) {
                UnicodeString errorMessage;
                if (!isPass(fTuple, errorMessage, status)) {
                    showFailure(errorMessage);
                }
            }
        }
        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 */
