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

/***********************************************************************
 * Modification history
 * Date        Name        Description
 * 07/09/2007  srl         Copied from dadrcoll.cpp
 ***********************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/tstdtmod.h"
#include "tsdate.h"
#include "dadrcal.h"
#include "unicode/calendar.h"
#include "intltest.h"
#include <string.h>
#include "unicode/schriter.h"
#include "unicode/regex.h"
#include "unicode/smpdtfmt.h"
#include "unicode/dbgutil.h"

#include <stdio.h>

DataDrivenCalendarTest::DataDrivenCalendarTest() {
    UErrorCode status = U_ZERO_ERROR;
    driver = TestDataModule::getTestDataModule("calendar", *this, status);
}

DataDrivenCalendarTest::~DataDrivenCalendarTest() {
    delete driver;
}

void DataDrivenCalendarTest::runIndexedTest(int32_t index, UBool exec,
        const char* &name, char* /*par */) {
    if (driver != NULL) {
        if (exec) {
            //  logln("Begin ");
        }
        const DataMap *info= NULL;
        UErrorCode status= U_ZERO_ERROR;
        TestData *testData = driver->createTestData(index, status);
        if (U_SUCCESS(status)) {
            name = testData->getName();
            if (testData->getInfo(info, status)) {
                log(info->getString("Description", status));
            }
            if (exec) {
                log(name);
                logln("---");
                logln("");

                processTest(testData);
            }
            delete testData;
        } else {
            name = "";
        }
    } else {
        errln("format/DataDriven*Test data (calendar.res) not initialized!");
        name = "";
    }

}

void DataDrivenCalendarTest::testOps(TestData *testData,
        const DataMap * /*settings*/) {
    UErrorCode status = U_ZERO_ERROR;
    const DataMap *currentCase= NULL;
    char toCalLoc[256] = "";

    // TODO: static strings?
    const UnicodeString kADD("add", "");
    const UnicodeString kROLL("roll", "");

    // Get 'from' time 
    CalendarFieldsSet fromSet, toSet, paramsSet, diffSet;
    SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"),
            status);
    if (U_FAILURE(status)) {
        errln("FAIL: Couldn't create SimpleDateFormat: %s\n",
                u_errorName(status));
        return;
    }
    // Start the processing
    int n = 0;
    while (testData->nextCase(currentCase, status)) {
        ++n;
        Calendar *toCalendar= NULL;
        Calendar *fromCalendar= NULL;

        // load parameters
        char theCase[200];
        sprintf(theCase, "[case %d]", n);
        UnicodeString caseString(theCase, "");
        // build to calendar
        //             Headers { "locale","from","operation","params","to" }
        // #1 locale
        const char *param = "locale";
        UnicodeString locale;
        UnicodeString testSetting = currentCase->getString(param, status);
        if (U_FAILURE(status)) {
            errln(caseString+": Unable to get param '"+param+"' "
                    + UnicodeString(" - "));
            continue;
        }
        testSetting.extract(0, testSetting.length(), toCalLoc, (const char*)0);
        fromCalendar = Calendar::createInstance(toCalLoc, status);
        if (U_FAILURE(status)) {
            errln(caseString+": Unable to instantiate calendar for "
                    +testSetting);
            continue;
        }

        fromSet.clear();
        // #2 'from' info
        param = "from";
        UnicodeString from = testSetting=currentCase->getString(param, status);
        if (U_FAILURE(status)) {
            errln(caseString+": Unable to get parameter '"+param+"' "
                    + UnicodeString(" - "));
            continue;
        }
        fromSet.parseFrom(testSetting, status);
        if (U_FAILURE(status)) {
            errln(caseString+": Failed to parse '"+param+"' parameter: "
                    +testSetting);
            continue;
        }

        // #4 'operation' info
        param = "operation";
        UnicodeString operation = testSetting=currentCase->getString(param,
                status);
        if (U_FAILURE(status)) {
            errln(caseString+": Unable to get parameter '"+param+"' "
                    + UnicodeString(" - "));
            continue;
        }
        if (U_FAILURE(status)) {
            errln(caseString+": Failed to parse '"+param+"' parameter: "
                    +testSetting);
            continue;
        }

        paramsSet.clear();
        // #3 'params' info
        param = "params";
        UnicodeString params = testSetting
                =currentCase->getString(param, status);
        if (U_FAILURE(status)) {
            errln(caseString+": Unable to get parameter '"+param+"' "
                    + UnicodeString(" - "));
            continue;
        }
        paramsSet.parseFrom(testSetting, status); // parse with inheritance.
        if (U_FAILURE(status)) {
            errln(caseString+": Failed to parse '"+param+"' parameter: "
                    +testSetting);
            continue;
        }

        toSet.clear();
        // #4 'to' info
        param = "to";
        UnicodeString to = testSetting=currentCase->getString(param, status);
        if (U_FAILURE(status)) {
            errln(caseString+": Unable to get parameter '"+param+"' "
                    + UnicodeString(" - "));
            continue;
        }
        toSet.parseFrom(testSetting, &fromSet, status); // parse with inheritance.
        if (U_FAILURE(status)) {
            errln(caseString+": Failed to parse '"+param+"' parameter: "
                    +testSetting);
            continue;
        }

        UnicodeString caseContentsString = locale+":  from "+from+": "
                +operation +" [[[ "+params+" ]]]   >>> "+to;
        logln(caseString+": "+caseContentsString);

        // ------
        // now, do it.

        /// prepare calendar
        fromSet.setOnCalendar(fromCalendar, status);
        if (U_FAILURE(status)) {
            errln(caseString+" FAIL: Failed to set on Source calendar: "
                    + u_errorName(status));
            return;
        }

        
        diffSet.clear();
        // Is the calendar sane after being set?
        if (!fromSet.matches(fromCalendar, diffSet, status)) {
            UnicodeString diffs = diffSet.diffFrom(fromSet, status);
            errln((UnicodeString)"FAIL: "+caseString
                    +", SET SOURCE calendar was not set: Differences: "+ diffs
                    +"', status: "+ u_errorName(status));
        } else if (U_FAILURE(status)) {
            errln("FAIL: "+caseString+" SET SOURCE calendar Failed to match: "
                    +u_errorName(status));
        } else {
            logln("PASS: "+caseString+" SET SOURCE calendar match.");
        }
        
        // to calendar - copy of from calendar
        toCalendar = fromCalendar->clone();

        /// perform op
        for (int q=0; q<UCAL_FIELD_COUNT; q++) {
            if (paramsSet.isSet((UCalendarDateFields)q)) {
                if (operation == kROLL) {
                    toCalendar->roll((UCalendarDateFields)q,
                            paramsSet.get((UCalendarDateFields)q), status);
                } else if (operation == kADD) {
                    toCalendar->add((UCalendarDateFields)q,
                            paramsSet.get((UCalendarDateFields)q), status);
                } else {
                    errln(caseString+ " FAIL: unknown operation "+ operation);
                }
                logln(operation + " of "+ paramsSet.get((UCalendarDateFields)q)
                        +" -> "+u_errorName(status));
            }
        }
        if (U_FAILURE(status)) {
            errln(caseString+" FAIL: after "+operation+" of "+params+" -> "
                    +u_errorName(status));
            continue;
        }

        // now - what's the result?
        diffSet.clear();

        if (!toSet.matches(toCalendar, diffSet, status)) {
            UnicodeString diffs = diffSet.diffFrom(toSet, status);
            errln((UnicodeString)"FAIL: "+caseString+" - , "+caseContentsString
                    +" Differences: "+ diffs +"', status: "
                    + u_errorName(status));
        } else if (U_FAILURE(status)) {
            errln("FAIL: "+caseString+" Match operation had an error: "
                    +u_errorName(status));
        } else {
            logln("PASS: "+caseString+" matched!");
        }

        delete fromCalendar;
        delete toCalendar;
    }
}

void DataDrivenCalendarTest::testConvert(int32_t n,
        const CalendarFieldsSet &fromSet, Calendar *fromCalendar,
        const CalendarFieldsSet &toSet, Calendar *toCalendar, UBool forward) {
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString thisString = (UnicodeString)"#"+n+" "+(forward ? "forward"
            : "reverse")+" "+fromCalendar->getType()+"->"+toCalendar->getType();

    fromCalendar->clear();

    fromSet.setOnCalendar(fromCalendar, status);
    if (U_FAILURE(status)) {
        errln("FAIL: Failed to set on Source calendar: %s", u_errorName(status));
        return;
    }

    CalendarFieldsSet diffSet;

    diffSet.clear();
    // Is the calendar sane at the first?
    if (!fromSet.matches(fromCalendar, diffSet, status)) {
        UnicodeString diffs = diffSet.diffFrom(fromSet, status);
        errln((UnicodeString)"FAIL: "+thisString
                +", SOURCE calendar was not set: Differences: "+ diffs
                +"', status: "+ u_errorName(status));
    } else if (U_FAILURE(status)) {
        errln("FAIL: "+thisString+" SOURCE calendar Failed to match: "
                +u_errorName(status));
    } else {
        logln("PASS: "+thisString+" SOURCE calendar match.");
    }

    //logln("Set Source calendar: " + from);

    UDate fromTime = fromCalendar->getTime(status);
    if (U_FAILURE(status)) {
        errln("FAIL: Failed to get Source time: %s", u_errorName(status));
        return;
    }

    diffSet.clear();
    // Is the calendar sane after being set?
    if (!fromSet.matches(fromCalendar, diffSet, status)) {
        UnicodeString diffs = diffSet.diffFrom(fromSet, status);
        errln((UnicodeString)"FAIL: "+thisString
                +", SET SOURCE calendar was not set: Differences: "+ diffs
                +"', status: "+ u_errorName(status));
    } else if (U_FAILURE(status)) {
        errln("FAIL: "+thisString+" SET SOURCE calendar Failed to match: "
                +u_errorName(status));
    } else {
        logln("PASS: "+thisString+" SET SOURCE calendar match.");
    }

    toCalendar->clear();
    toCalendar->setTime(fromTime, status);
    if (U_FAILURE(status)) {
        errln("FAIL: Failed to set Target time: %s", u_errorName(status));
        return;
    }

    diffSet.clear();
    if (!toSet.matches(toCalendar, diffSet, status)) {
        UnicodeString diffs = diffSet.diffFrom(toSet, status);
        errln((UnicodeString)"FAIL: "+thisString+", Differences: "+ diffs
                +"', status: "+ u_errorName(status));
        SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy G"), status);
        UnicodeString fromString;
        fmt.format(fromTime, fromString);
        logln("Source Time: "+fromString+", Source Calendar: "
                +fromCalendar->getType());
    } else if (U_FAILURE(status)) {
        errln("FAIL: "+thisString+" Failed to match: "+u_errorName(status));
    } else {
        logln("PASS: "+thisString+" match.");
    }
}

void DataDrivenCalendarTest::testConvert(TestData *testData,
        const DataMap *settings, UBool forward) {
    UErrorCode status = U_ZERO_ERROR;
    Calendar *toCalendar= NULL;
    const DataMap *currentCase= NULL;
    char toCalLoc[256] = "";
    char fromCalLoc[256] = "";
    // build to calendar
    UnicodeString testSetting = settings->getString("ToCalendar", status);
    if (U_SUCCESS(status)) {
        testSetting.extract(0, testSetting.length(), toCalLoc, (const char*)0);
        toCalendar = Calendar::createInstance(toCalLoc, status);
        if (U_FAILURE(status)) {
            errln("Unable to instantiate ToCalendar for "+testSetting);
            return;
        }
    }

    CalendarFieldsSet fromSet, toSet, diffSet;
    SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"),
            status);
    if (U_FAILURE(status)) {
        errln("FAIL: Couldn't create SimpleDateFormat: %s\n",
                u_errorName(status));
        return;
    }
    // Start the processing
    int n = 0;
    while (testData->nextCase(currentCase, status)) {
        ++n;
        Calendar *fromCalendar= NULL;
        UnicodeString locale = currentCase->getString("locale", status);
        if (U_SUCCESS(status)) {
            locale.extract(0, locale.length(), fromCalLoc, (const char*)0); // default codepage.  Invariant codepage doesn't have '@'!
            fromCalendar = Calendar::createInstance(fromCalLoc, status);
            if (U_FAILURE(status)) {
                errln("Unable to instantiate fromCalendar for "+locale);
                return;
            }
        } else {
            errln("No 'locale' line.");
            continue;
        }

        fromSet.clear();
        toSet.clear();

        UnicodeString from = currentCase->getString("from", status);
        if (U_FAILURE(status)) {
            errln("No 'from' line.");
            continue;
        }
        fromSet.parseFrom(from, status);
        if (U_FAILURE(status)) {
            errln("Failed to parse 'from' parameter: "+from);
            continue;
        }
        UnicodeString to = currentCase->getString("to", status);
        if (U_FAILURE(status)) {
            errln("No 'to' line.");
            continue;
        }
        toSet.parseFrom(to, &fromSet, status);
        if (U_FAILURE(status)) {
            errln("Failed to parse 'to' parameter: "+to);
            continue;
        }

        // now, do it.
        if (forward) {
            logln((UnicodeString)"#"+n+" "+locale+"/"+from+" >>> "+toCalLoc+"/"
                    +to);
            testConvert(n, fromSet, fromCalendar, toSet, toCalendar, forward);
        } else {
            logln((UnicodeString)"#"+n+" "+locale+"/"+from+" <<< "+toCalLoc+"/"
                    +to);
            testConvert(n, toSet, toCalendar, fromSet, fromCalendar, forward);
        }

        delete fromCalendar;
    }
    delete toCalendar;
}

void DataDrivenCalendarTest::processTest(TestData *testData) {
    //Calendar *cal= NULL;
    //const UChar *arguments= NULL;
    //int32_t argLen = 0;
    char testType[256];
    const DataMap *settings= NULL;
    //const UChar *type= NULL;
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString testSetting;
    int n = 0;
    while (testData->nextSettings(settings, status)) {
        status = U_ZERO_ERROR;
        // try to get a locale
        testSetting = settings->getString("Type", status);
        if (U_SUCCESS(status)) {
            if ((++n)>0) {
                logln("---");
            }
            logln(testSetting + "---");
            testSetting.extract(0, testSetting.length(), testType, "");
        } else {
            errln("Unable to extract 'Type'. Skipping..");
            continue;
        }

        if (!strcmp(testType, "convert_fwd")) {
            testConvert(testData, settings, true);
        } else if (!strcmp(testType, "convert_rev")) {
            testConvert(testData, settings, false);
        } else if (!strcmp(testType, "ops")) {
            testOps(testData, settings);
        } else {
            errln("Unknown type: %s", testType);
        }
    }
}

#endif
