/********************************************************************
 * COPYRIGHT:
 * Copyright (c) 2002-2014, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

//
//   dcfmtest.cpp
//
//     Decimal Formatter tests, data driven. 
//

#include "intltest.h"

#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_REGULAR_EXPRESSIONS

#include "unicode/regex.h"
#include "unicode/uchar.h"
#include "unicode/ustring.h"
#include "unicode/unistr.h"
#include "unicode/dcfmtsym.h"
#include "unicode/decimfmt.h"
#include "unicode/locid.h"
#include "cmemory.h"
#include "dcfmtest.h"
#include "util.h"
#include "cstring.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#if !defined(_MSC_VER)
namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
#endif

#include <string>
#include <iostream>

//---------------------------------------------------------------------------
//
//  Test class boilerplate
//
//---------------------------------------------------------------------------
DecimalFormatTest::DecimalFormatTest()
{
}


DecimalFormatTest::~DecimalFormatTest()
{
}



void DecimalFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    if (exec) logln("TestSuite DecimalFormatTest: ");
    switch (index) {

#if !UCONFIG_NO_FILE_IO
        case 0: name = "DataDrivenTests";
            if (exec) DataDrivenTests();
            break;
#else
        case 0: name = "skip";
            break;
#endif

        default: name = "";
            break; //needed to end loop
    }
}


//---------------------------------------------------------------------------
//
//   Error Checking / Reporting macros used in all of the tests.
//
//---------------------------------------------------------------------------
#define DF_CHECK_STATUS {if (U_FAILURE(status)) \
    {dataerrln("DecimalFormatTest failure at line %d.  status=%s", \
    __LINE__, u_errorName(status)); return 0;}}

#define DF_ASSERT(expr) {if ((expr)==FALSE) {errln("DecimalFormatTest failure at line %d.\n", __LINE__);};}

#define DF_ASSERT_FAIL(expr, errcode) {UErrorCode status=U_ZERO_ERROR; (expr);\
if (status!=errcode) {dataerrln("DecimalFormatTest failure at line %d.  Expected status=%s, got %s", \
    __LINE__, u_errorName(errcode), u_errorName(status));};}

#define DF_CHECK_STATUS_L(line) {if (U_FAILURE(status)) {errln( \
    "DecimalFormatTest failure at line %d, from %d.  status=%d\n",__LINE__, (line), status); }}

#define DF_ASSERT_L(expr, line) {if ((expr)==FALSE) { \
    errln("DecimalFormatTest failure at line %d, from %d.", __LINE__, (line)); return;}}



//
//  InvariantStringPiece
//    Wrap a StringPiece around the extracted invariant data of a UnicodeString.
//    The data is guaranteed to be nul terminated.  (This is not true of StringPiece
//    in general, but is true of InvariantStringPiece)
//
class InvariantStringPiece: public StringPiece {
  public:
    InvariantStringPiece(const UnicodeString &s);
    ~InvariantStringPiece() {};
  private:
    MaybeStackArray<char, 20>  buf;
};

InvariantStringPiece::InvariantStringPiece(const UnicodeString &s) {
    int32_t  len = s.length();
    if (len+1 > buf.getCapacity()) {
        buf.resize(len+1);
    }
    // Buffer size is len+1 so that s.extract() will nul-terminate the string.
    s.extract(0, len, buf.getAlias(), len+1, US_INV);
    this->set(buf.getAlias(), len);
}


//  UnicodeStringPiece
//    Wrap a StringPiece around the extracted (to the default charset) data of
//    a UnicodeString.  The extracted data is guaranteed to be nul terminated.
//    (This is not true of StringPiece in general, but is true of UnicodeStringPiece)
//
class UnicodeStringPiece: public StringPiece {
  public:
    UnicodeStringPiece(const UnicodeString &s);
    ~UnicodeStringPiece() {};
  private:
    MaybeStackArray<char, 20>  buf;
};

UnicodeStringPiece::UnicodeStringPiece(const UnicodeString &s) {
    int32_t  len = s.length();
    int32_t  capacity = buf.getCapacity();
    int32_t requiredCapacity = s.extract(0, len, buf.getAlias(), capacity) + 1;
    if (capacity < requiredCapacity) {
        buf.resize(requiredCapacity);
        capacity = requiredCapacity;
        s.extract(0, len, buf.getAlias(), capacity);
    }
    this->set(buf.getAlias(), requiredCapacity - 1);
}



//---------------------------------------------------------------------------
//
//      DataDrivenTests  
//             The test cases are in a separate data file,
//
//---------------------------------------------------------------------------

// Translate a Formattable::type enum value to a string, for error message formatting.
static const char *formattableType(Formattable::Type typ) {
    static const char *types[] = {"kDate",
                                  "kDouble",
                                  "kLong",
                                  "kString",
                                  "kArray",
                                  "kInt64",
                                  "kObject"
                                  };
    if (typ<0 || typ>Formattable::kObject) {
        return "Unknown";
    }
    return types[typ];
}

const char *
DecimalFormatTest::getPath(char *buffer, const char *filename) {
    UErrorCode status=U_ZERO_ERROR;
    const char *testDataDirectory = IntlTest::getSourceTestData(status);
    DF_CHECK_STATUS;

    strcpy(buffer, testDataDirectory);
    strcat(buffer, filename);
    return buffer;
}

void DecimalFormatTest::DataDrivenTests() {
    char tdd[2048];
    const char *srcPath;
    UErrorCode  status  = U_ZERO_ERROR;
    int32_t     lineNum = 0;

    //
    //  Open and read the test data file.
    //
    srcPath=getPath(tdd, "dcfmtest.txt");
    if(srcPath==NULL) {
        return; /* something went wrong, error already output */
    }

    int32_t    len;
    UChar *testData = ReadAndConvertFile(srcPath, len, status);
    if (U_FAILURE(status)) {
        return; /* something went wrong, error already output */
    }

    //
    //  Put the test data into a UnicodeString
    //
    UnicodeString testString(FALSE, testData, len);

    RegexMatcher    parseLineMat(UnicodeString(
            "(?i)\\s*parse\\s+"
            "\"([^\"]*)\"\\s+"           // Capture group 1: input text
            "([ild])\\s+"                // Capture group 2: expected parsed type
            "\"([^\"]*)\"\\s+"           // Capture group 3: expected parsed decimal
            "\\s*(?:#.*)?"),             // Trailing comment
         0, status);

    RegexMatcher    formatLineMat(UnicodeString(
            "(?i)\\s*format\\s+"
            "(\\S+)\\s+"                 // Capture group 1: pattern
            "(ceiling|floor|down|up|halfeven|halfdown|halfup|default|unnecessary)\\s+"  // Capture group 2: Rounding Mode
            "\"([^\"]*)\"\\s+"           // Capture group 3: input
            "\"([^\"]*)\""               // Capture group 4: expected output
            "\\s*(?:#.*)?"),             // Trailing comment
         0, status);

    RegexMatcher    commentMat    (UNICODE_STRING_SIMPLE("\\s*(#.*)?$"), 0, status);
    RegexMatcher    lineMat(UNICODE_STRING_SIMPLE("(?m)^(.*?)$"), testString, 0, status);

    if (U_FAILURE(status)){
        dataerrln("Construct RegexMatcher() error.");
        delete [] testData;
        return;
    }

    //
    //  Loop over the test data file, once per line.
    //
    while (lineMat.find()) {
        lineNum++;
        if (U_FAILURE(status)) {
            dataerrln("File dcfmtest.txt, line %d: ICU Error \"%s\"", lineNum, u_errorName(status));
        }

        status = U_ZERO_ERROR;
        UnicodeString testLine = lineMat.group(1, status);
        // printf("%s\n", UnicodeStringPiece(testLine).data());
        if (testLine.length() == 0) {
            continue;
        }

        //
        // Parse the test line.  Skip blank and comment only lines.
        // Separate out the three main fields - pattern, flags, target.
        //

        commentMat.reset(testLine);
        if (commentMat.lookingAt(status)) {
            // This line is a comment, or blank.
            continue;
        }


        //
        //  Handle "parse" test case line from file
        //
        parseLineMat.reset(testLine);
        if (parseLineMat.lookingAt(status)) {
            execParseTest(lineNum,
                          parseLineMat.group(1, status),    // input
                          parseLineMat.group(2, status),    // Expected Type
                          parseLineMat.group(3, status),    // Expected Decimal String
                          status
                          );
            continue;
        }

        //
        //  Handle "format" test case line
        //
        formatLineMat.reset(testLine);
        if (formatLineMat.lookingAt(status)) {
            execFormatTest(lineNum,
                           formatLineMat.group(1, status),    // Pattern
                           formatLineMat.group(2, status),    // rounding mode
                           formatLineMat.group(3, status),    // input decimal number
                           formatLineMat.group(4, status),    // expected formatted result
                           kFormattable,
                           status);

            execFormatTest(lineNum,
                           formatLineMat.group(1, status),    // Pattern
                           formatLineMat.group(2, status),    // rounding mode
                           formatLineMat.group(3, status),    // input decimal number
                           formatLineMat.group(4, status),    // expected formatted result
                           kStringPiece,
                           status);
            continue;
        }

        //
        //  Line is not a recognizable test case.
        //
        errln("Badly formed test case at line %d.\n%s\n", 
             lineNum, UnicodeStringPiece(testLine).data());

    }

    delete [] testData;
}



void DecimalFormatTest::execParseTest(int32_t lineNum,
                                     const UnicodeString &inputText,
                                     const UnicodeString &expectedType,
                                     const UnicodeString &expectedDecimal,
                                     UErrorCode &status) {
    
    if (U_FAILURE(status)) {
        return;
    }

    DecimalFormatSymbols symbols(Locale::getUS(), status);
    UnicodeString pattern = UNICODE_STRING_SIMPLE("####");
    DecimalFormat format(pattern, symbols, status);
    Formattable   result;
    if (U_FAILURE(status)) {
        dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
            lineNum, u_errorName(status));
        return;
    }

    ParsePosition pos;
    int32_t expectedParseEndPosition = inputText.length();

    format.parse(inputText, result, pos);

    if (expectedParseEndPosition != pos.getIndex()) {
        errln("file dcfmtest.txt, line %d: Expected parse position afeter parsing: %d.  "
              "Actual parse position: %d", expectedParseEndPosition, pos.getIndex());
        return;
    }

    char   expectedTypeC[2];
    expectedType.extract(0, 1, expectedTypeC, 2, US_INV);
    Formattable::Type expectType = Formattable::kDate;
    switch (expectedTypeC[0]) {
      case 'd': expectType = Formattable::kDouble; break;
      case 'i': expectType = Formattable::kLong;   break;
      case 'l': expectType = Formattable::kInt64;  break;
      default:
          errln("file dcfmtest.tx, line %d: unrecongized expected type \"%s\"",
              lineNum, InvariantStringPiece(expectedType).data());
          return;
    }
    if (result.getType() != expectType) {
        errln("file dcfmtest.txt, line %d: expectedParseType(%s) != actual parseType(%s)",
             lineNum, formattableType(expectType), formattableType(result.getType()));
        return;
    }

    StringPiece decimalResult = result.getDecimalNumber(status);
    if (U_FAILURE(status)) {
        errln("File %s, line %d: error %s.  Line in file dcfmtest.txt:  %d:",
            __FILE__, __LINE__, u_errorName(status), lineNum);
        return;
    }

    InvariantStringPiece expectedResults(expectedDecimal);
    if (decimalResult != expectedResults) {
        errln("file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
            lineNum, expectedResults.data(), decimalResult.data());
    }
    
    return;
}


void DecimalFormatTest::execFormatTest(int32_t lineNum,
                           const UnicodeString &pattern,     // Pattern
                           const UnicodeString &round,       // rounding mode
                           const UnicodeString &input,       // input decimal number
                           const UnicodeString &expected,    // expected formatted result
                           EFormatInputType inType,          // input number type
                           UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }

    DecimalFormatSymbols symbols(Locale::getUS(), status);
    // printf("Pattern = %s\n", UnicodeStringPiece(pattern).data());
    DecimalFormat fmtr(pattern, symbols, status);
    if (U_FAILURE(status)) {
        dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
            lineNum, u_errorName(status));
        return;
    }
    if (round=="ceiling") {
        fmtr.setRoundingMode(DecimalFormat::kRoundCeiling);
    } else if (round=="floor") {
        fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
    } else if (round=="down") {
        fmtr.setRoundingMode(DecimalFormat::kRoundDown);
    } else if (round=="up") {
        fmtr.setRoundingMode(DecimalFormat::kRoundUp);
    } else if (round=="halfeven") {
        fmtr.setRoundingMode(DecimalFormat::kRoundHalfEven);
    } else if (round=="halfdown") {
        fmtr.setRoundingMode(DecimalFormat::kRoundHalfDown);
    } else if (round=="halfup") {
        fmtr.setRoundingMode(DecimalFormat::kRoundHalfUp);
    } else if (round=="default") {
        // don't set any value.
    } else if (round=="unnecessary") {
        fmtr.setRoundingMode(DecimalFormat::kRoundUnnecessary);
    } else {
        fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
        errln("file dcfmtest.txt, line %d: Bad rounding mode \"%s\"",
                lineNum, UnicodeStringPiece(round).data());
    }

    const char *typeStr = "Unknown";
    UnicodeString result;
    UnicodeStringPiece spInput(input);

    switch (inType) {
    case kFormattable:
        {
            typeStr = "Formattable";
            Formattable fmtbl;
            fmtbl.setDecimalNumber(spInput, status);
            fmtr.format(fmtbl, result, NULL, status);
        }
        break;
    case kStringPiece:
        typeStr = "StringPiece";
        fmtr.format(spInput, result, NULL, status);
        break;
    }

    if ((status == U_FORMAT_INEXACT_ERROR) && (result == "") && (expected == "Inexact")) {
        // Test succeeded.
        status = U_ZERO_ERROR;
        return;
    }

    if (U_FAILURE(status)) {
        errln("[%s] file dcfmtest.txt, line %d: format() returned %s.",
            typeStr, lineNum, u_errorName(status));
        status = U_ZERO_ERROR;
        return;
    }
    
    if (result != expected) {
        errln("[%s] file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
            typeStr, lineNum, UnicodeStringPiece(expected).data(), UnicodeStringPiece(result).data());
    }
}


//-------------------------------------------------------------------------------
//      
//  Read a text data file, convert it from UTF-8 to UChars, and return the data
//    in one big UChar * buffer, which the caller must delete.
//
//    (Lightly modified version of a similar function in regextst.cpp)
//
//--------------------------------------------------------------------------------
UChar *DecimalFormatTest::ReadAndConvertFile(const char *fileName, int32_t &ulen,
                                     UErrorCode &status) {
    UChar       *retPtr  = NULL;
    char        *fileBuf = NULL;
    const char  *fileBufNoBOM = NULL;
    FILE        *f       = NULL;

    ulen = 0;
    if (U_FAILURE(status)) {
        return retPtr;
    }

    //
    //  Open the file.
    //
    f = fopen(fileName, "rb");
    if (f == 0) {
        dataerrln("Error opening test data file %s\n", fileName);
        status = U_FILE_ACCESS_ERROR;
        return NULL;
    }
    //
    //  Read it in
    //
    int32_t            fileSize;
    int32_t            amtRead;
    int32_t            amtReadNoBOM;

    fseek( f, 0, SEEK_END);
    fileSize = ftell(f);
    fileBuf = new char[fileSize];
    fseek(f, 0, SEEK_SET);
    amtRead = fread(fileBuf, 1, fileSize, f);
    if (amtRead != fileSize || fileSize <= 0) {
        errln("Error reading test data file.");
        goto cleanUpAndReturn;
    }

    //
    // Look for a UTF-8 BOM on the data just read.
    //    The test data file is UTF-8.
    //    The BOM needs to be there in the source file to keep the Windows & 
    //    EBCDIC machines happy, so force an error if it goes missing.  
    //    Many Linux editors will silently strip it.
    //
    fileBufNoBOM = fileBuf + 3;
    amtReadNoBOM = amtRead - 3;
    if (fileSize<3 || uprv_strncmp(fileBuf, "\xEF\xBB\xBF", 3) != 0) {
        // TODO:  restore this check.
        errln("Test data file %s is missing its BOM", fileName);
        fileBufNoBOM = fileBuf;
        amtReadNoBOM = amtRead;
    }

    //
    // Find the length of the input in UTF-16 UChars
    //  (by preflighting the conversion)
    //
    u_strFromUTF8(NULL, 0, &ulen, fileBufNoBOM, amtReadNoBOM, &status);

    //
    // Convert file contents from UTF-8 to UTF-16
    //
    if (status == U_BUFFER_OVERFLOW_ERROR) {
        // Buffer Overflow is expected from the preflight operation.
        status = U_ZERO_ERROR;
        retPtr = new UChar[ulen+1];
        u_strFromUTF8(retPtr, ulen+1, NULL, fileBufNoBOM, amtReadNoBOM, &status);
    }

cleanUpAndReturn:
    fclose(f);
    delete[] fileBuf;
    if (U_FAILURE(status)) {
        errln("ICU Error \"%s\"\n", u_errorName(status));
        delete retPtr;
        retPtr = NULL;
    };
    return retPtr;
}

#endif  /* !UCONFIG_NO_REGULAR_EXPRESSIONS  */

