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

#include "aliastst.h"
#include "unicode/calendar.h"
#include "unicode/smpdtfmt.h"
#include "unicode/datefmt.h"
#include "unicode/unistr.h"
#include "unicode/coll.h"
#include "unicode/resbund.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const char* _LOCALE_ALIAS[][2] = {
    {"in", "id"},
    {"in_ID", "id_ID"},
    {"iw", "he"},
    {"iw_IL", "he_IL"},
    {"ji", "yi"},
    {"en_BU", "en_MM"},
    {"en_DY", "en_BJ"},
    {"en_HV", "en_BF"},
    {"en_NH", "en_VU"},
    {"en_RH", "en_ZW"},
    {"en_TP", "en_TL"},
    {"en_ZR", "en_CD"}
};

const int _LOCALE_NUMBER = 12;

void LocaleAliasTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ){
    switch (index) {
        TESTCASE(0, TestCalendar);
        TESTCASE(1, TestDateFormat);
        TESTCASE(2, TestCollation);
        TESTCASE(3, TestULocale);
        TESTCASE(4, TestUResourceBundle);
        TESTCASE(5, TestDisplayName);
        // keep the last index in sync with the condition in default:

        default:
            if (index <= 5) { // keep this in sync with the last index!
                name = "(test omitted by !UCONFIG_NO_FORMATTING)";
            } else {
                name = "";
            }
            break; //needed to end loop
    }
}

void LocaleAliasTest::TestCalendar() {
#if !UCONFIG_NO_FORMATTING
    UErrorCode status = U_ZERO_ERROR;
    for (int i=0; i<_LOCALE_NUMBER; i++) {
        Locale oldLoc(_LOCALE_ALIAS[i][0]);
        Locale newLoc(_LOCALE_ALIAS[i][1]);
        if(!isLocaleAvailable(_LOCALE_ALIAS[i][1])){
            logln(UnicodeString(newLoc.getName())+" is not available. Skipping!");
            continue;
        }
        logln("\nold locale:%s   new locale:%s",oldLoc.getName(),newLoc.getName());
        Calendar* c1 = Calendar::createInstance(oldLoc, status);
        Calendar* c2 = Calendar::createInstance(newLoc, status);

        //Test function "getLocale(ULocale.VALID_LOCALE)"
        const char* l1 = c1->getLocaleID(ULOC_VALID_LOCALE, status);
        const char* l2 = c2->getLocaleID(ULOC_VALID_LOCALE, status);
        if (strcmp(newLoc.getName(), l1)!=0) {
            errln("CalendarTest: newLoc!=l1: newLoc= "+UnicodeString(newLoc.getName()) +" l1= "+UnicodeString(l1));
        }
        if (strcmp(l1, l2)!=0) {
            errln("CalendarTest: l1!=l2: l1= "+UnicodeString(l1) +" l2= "+UnicodeString(l2));
        }
        if(!(c1==c2)){
            errln("CalendarTest: c1!=c2.  newLoc= "+UnicodeString(newLoc.getName())  +" oldLoc= "+UnicodeString(oldLoc.getName()));
        }
        logln("Calendar(getLocale) old:"+UnicodeString(l1)+"   new:"+UnicodeString(l2));   
        delete c1;
        delete c2;
    }
#endif
}
void LocaleAliasTest::TestDateFormat() {
#if !UCONFIG_NO_FORMATTING
    UErrorCode status = U_ZERO_ERROR;
    for (int i=0; i<_LOCALE_NUMBER; i++) {
        Locale oldLoc(_LOCALE_ALIAS[i][0]);
        Locale newLoc(_LOCALE_ALIAS[i][1]);
        if(!isLocaleAvailable(_LOCALE_ALIAS[i][1])){
            logln(UnicodeString(newLoc.getName())+" is not available. Skipping!");
            continue;
        }
        logln("\nold locale:%s   new locale:%s",oldLoc.getName(),newLoc.getName());

        DateFormat* df1 = DateFormat::createDateInstance(DateFormat::FULL, oldLoc);
        DateFormat* df2 = DateFormat::createDateInstance(DateFormat::FULL, newLoc);

        //Test function "getLocale"
        const char* l1 = df1->getLocaleID(ULOC_VALID_LOCALE, status);
        const char* l2 = df2->getLocaleID(ULOC_VALID_LOCALE, status);
        if (strcmp(newLoc.getName(), l1)!=0) {
            errln("CalendarTest: newLoc!=l1: newLoc= "+UnicodeString(newLoc.getName()) +" l1= "+UnicodeString(l1));
        }
        if (strcmp(l1, l2)!=0) {
            errln("TestDateFormat: l1!=l2: l1= "+UnicodeString(l1) +" l2= "+UnicodeString(l2));
        }
        if(!(df1==df2)){
            errln("TestDateFormat: c1!=c2.  newLoc= "+UnicodeString(newLoc.getName())  +" oldLoc= "+UnicodeString(oldLoc.getName()));
        }
        logln("DateFormat(getLocale) old:%s   new:%s",l1,l2);

        delete df1;
        delete df2;
    }
#endif
}
void LocaleAliasTest::TestCollation() {
#if !UCONFIG_NO_COLLATION
    UErrorCode status = U_ZERO_ERROR;
    for (int i=0; i<_LOCALE_NUMBER; i++) {
        Locale oldLoc(_LOCALE_ALIAS[i][0]);
        Locale newLoc(_LOCALE_ALIAS[i][1]);
        if(!isLocaleAvailable(_LOCALE_ALIAS[i][1])){
            logln(UnicodeString(newLoc.getName())+" is not available. Skipping!");
            continue;
        }
        logln("\nold locale:%s   new locale:%s",oldLoc.getName(),newLoc.getName());

        Collator* c1 = Collator::createInstance(oldLoc, status);
        Collator* c2 = Collator::createInstance(newLoc, status);

        Locale l1 = c1->getLocale(ULOC_VALID_LOCALE, status);
        Locale l2 = c2->getLocale(ULOC_VALID_LOCALE, status);

        if (strcmp(newLoc.getName(), l1.getName())!=0) {
            errln("CalendarTest: newLoc!=l1: newLoc= "+UnicodeString(newLoc.getName()) +" l1= "+UnicodeString(l1.getName()));
        }
        if (strcmp(l1.getName(), l2.getName())!=0) {
            errln("CollationTest: l1!=l2: l1= "+UnicodeString(l1.getName()) +" l2= "+UnicodeString(l2.getName()));
        }
        if(!(c1==c2)){
            errln("CollationTest: c1!=c2.  newLoc= "+UnicodeString(newLoc.getName())  +" oldLoc= "+UnicodeString(oldLoc.getName()));
        }
        logln("Collator(getLocale) old:%s   new:%s", l1.getName(), l2.getName());
        delete c1;
        delete c2;
    }
#endif
}
void LocaleAliasTest::TestULocale() {
    for (int i=0; i<_LOCALE_NUMBER; i++) {
        Locale oldLoc(_LOCALE_ALIAS[i][0]);
        Locale newLoc(_LOCALE_ALIAS[i][1]);
        if(!isLocaleAvailable(_LOCALE_ALIAS[i][1])){
            logln(UnicodeString(newLoc.getName())+" is not available. Skipping!");
            continue;
        }
        logln("\nold locale:%s   new locale:%s",oldLoc.getName(),newLoc.getName());

        UnicodeString name1, name2;
        oldLoc.getDisplayName(name1);
        newLoc.getDisplayName(name2);
        if (name1!=name2) {
            errln("DisplayNames are not equal.  newLoc= "+UnicodeString(newLoc.getName())  +" oldLoc= "+UnicodeString(oldLoc.getName()));
        }
        log("ULocale(getDisplayName) old:");
        log(name1);
        log("   new:");
        logln(name2);
    }
}
LocaleAliasTest::LocaleAliasTest(){
    UErrorCode status = U_ZERO_ERROR;
    resIndex = ures_open(NULL,"res_index", &status);
    if(U_FAILURE(status)){
        errln("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
        resIndex=NULL;
    }
    defLocale = Locale::getDefault();
    Locale::setDefault(Locale::getUS(), status); 
}
LocaleAliasTest::~LocaleAliasTest(){
    /* reset the default locale */
    UErrorCode status = U_ZERO_ERROR;
    Locale::setDefault(defLocale, status); 
    ures_close(resIndex);
    if(U_FAILURE(status)){
        errln("Could not reset the default locale. Exiting. Error: %s\n", u_errorName(status));
    }
}
UBool LocaleAliasTest::isLocaleAvailable(const char* loc){
    if(resIndex==NULL){
        return FALSE;
    }
    UErrorCode status = U_ZERO_ERROR;
    int32_t len = 0;
    ures_getStringByKey(resIndex, loc,&len, &status);
    if(U_FAILURE(status)){
        return FALSE; 
    }
    return TRUE;
}
void LocaleAliasTest::TestDisplayName() {
    int32_t availableNum =0;
    const Locale* available = Locale::getAvailableLocales(availableNum);
    for (int i=0; i<_LOCALE_NUMBER; i++) {
        Locale oldLoc(_LOCALE_ALIAS[i][0]);
        Locale newLoc(_LOCALE_ALIAS[i][1]);
        if(!isLocaleAvailable(_LOCALE_ALIAS[i][1])){
            logln(UnicodeString(newLoc.getName())+" is not available. Skipping!");
            continue;
        }
        for(int j=0; j<availableNum; j++){
            UnicodeString dipLocName = UnicodeString(available[j].getName());
            const UnicodeString oldCountry = oldLoc.getDisplayCountry(dipLocName);
            const UnicodeString newCountry = newLoc.getDisplayCountry(dipLocName);
            const UnicodeString oldLang = oldLoc.getDisplayLanguage(dipLocName);
            const UnicodeString newLang = newLoc.getDisplayLanguage(dipLocName);

            // is  there  display name for the current country ID               
            if(newCountry != newLoc.getCountry()){
                if(oldCountry!=newCountry){
                    errln("getCountry() failed for "+ UnicodeString(oldLoc.getName()) +" oldCountry= "+ prettify(oldCountry) +" newCountry = "+prettify(newCountry)+ " in display locale "+ UnicodeString(available[j].getName()));
                }
            }
            //there is a display name for the current lang ID               
            if(newLang != newLoc.getLanguage()){
                if(oldLang != newLang){
                    errln("getLanguage() failed for " + UnicodeString(oldLoc.getName()) + " oldLang = "+ prettify(oldLang) +" newLang = "+prettify(newLang)+ " in display locale "+UnicodeString(available[j].getName()));
                }
            }
        }
    }
}
void LocaleAliasTest::TestUResourceBundle() {

    UErrorCode status = U_ZERO_ERROR;
    for (int i=0; i<_LOCALE_NUMBER; i++) {
        Locale oldLoc(_LOCALE_ALIAS[i][0]);
        Locale newLoc(_LOCALE_ALIAS[i][1]);
        if(!isLocaleAvailable(_LOCALE_ALIAS[i][1])){
            logln(UnicodeString(newLoc.getName())+" is not available. Skipping!");
            continue;
        }
        logln("\nold locale:%s   new locale:%s",oldLoc.getName(),newLoc.getName());

        ResourceBundle* rb1 = NULL;
        ResourceBundle* rb2 = NULL;

        const char* testdatapath=loadTestData(status);

        UnicodeString us1("NULL");
        UnicodeString us2("NULL");
        rb1 = new ResourceBundle(testdatapath, oldLoc, status);
        if (U_FAILURE(U_ZERO_ERROR)) {

        } else {
            us1 = rb1->getStringEx("locale", status);
        }
        rb2 = new ResourceBundle(testdatapath, newLoc, status);
        if (U_FAILURE(U_ZERO_ERROR)){

        } else {
            us2 = rb2->getStringEx("locale", status);
        }
        UnicodeString uNewLoc(newLoc.getName());
        if (us1.compare(uNewLoc)!=0 || us1.compare(us2)!=0 || status!=U_ZERO_ERROR) {

        }
        log("UResourceBundle(getStringEx) old:");
        log(us1);
        log("   new:");
        logln(us2);

        if (rb1!=NULL) {
            delete rb1;
        }
        if (rb2!=NULL) {
            delete rb2;
        }
    }

}
