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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "nmfmapts.h"

#include "unicode/numfmt.h"
#include "unicode/decimfmt.h"
#include "unicode/locid.h"
#include "unicode/unum.h"
#include "unicode/strenum.h"

// This is an API test, not a unit test.  It doesn't test very many cases, and doesn't
// try to test the full functionality.  It just calls each function in the class and
// verifies that it works on a basic level.

void IntlTestNumberFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    if (exec) logln("TestSuite NumberFormatAPI");
    switch (index) {
        case 0: name = "NumberFormat API test"; 
                if (exec) {
                    logln("NumberFormat API test---"); logln("");
                    UErrorCode status = U_ZERO_ERROR;
                    Locale saveLocale;
                    Locale::setDefault(Locale::getEnglish(), status);
                    if(U_FAILURE(status)) {
                        errln("ERROR: Could not set default locale, test may not give correct results");
                    }
                    testAPI(/* par */);
                    Locale::setDefault(saveLocale, status);
                }
                break;
        case 1: name = "NumberFormatRegistration"; 
                if (exec) {
                    logln("NumberFormat Registration test---"); logln("");
                    UErrorCode status = U_ZERO_ERROR;
                    Locale saveLocale;
                    Locale::setDefault(Locale::getEnglish(), status);
                    if(U_FAILURE(status)) {
                        errln("ERROR: Could not set default locale, test may not give correct results");
                    }
                    testRegistration();
                    Locale::setDefault(saveLocale, status);
                }
                break;
        default: name = ""; break;
    }
}

/**
 * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
 * NumberFormat.
 */
void IntlTestNumberFormatAPI::testAPI(/* char* par */)
{
    UErrorCode status = U_ZERO_ERROR;

// ======= Test constructors

    logln("Testing NumberFormat constructors");

    NumberFormat *def = NumberFormat::createInstance(status);
    if(U_FAILURE(status)) {
        dataerrln("ERROR: Could not create NumberFormat (default) - %s", u_errorName(status));
    }

    status = U_ZERO_ERROR;
    NumberFormat *fr = NumberFormat::createInstance(Locale::getFrench(), status);
    if(U_FAILURE(status)) {
        dataerrln("ERROR: Could not create NumberFormat (French) - %s", u_errorName(status));
    }

    NumberFormat *cur = NumberFormat::createCurrencyInstance(status);
    if(U_FAILURE(status)) {
        dataerrln("ERROR: Could not create NumberFormat (currency, default) - %s", u_errorName(status));
    }

    status = U_ZERO_ERROR;
    NumberFormat *cur_fr = NumberFormat::createCurrencyInstance(Locale::getFrench(), status);
    if(U_FAILURE(status)) {
        dataerrln("ERROR: Could not create NumberFormat (currency, French) - %s", u_errorName(status));
    }

    NumberFormat *per = NumberFormat::createPercentInstance(status);
    if(U_FAILURE(status)) {
        dataerrln("ERROR: Could not create NumberFormat (percent, default) - %s", u_errorName(status));
    }

    status = U_ZERO_ERROR;
    NumberFormat *per_fr = NumberFormat::createPercentInstance(Locale::getFrench(), status);
    if(U_FAILURE(status)) {
        dataerrln("ERROR: Could not create NumberFormat (percent, French) - %s", u_errorName(status));
    }

// ======= Test equality
if (per_fr != NULL && cur_fr != NULL)
{
    logln("Testing equality operator");
    
    if( *per_fr == *cur_fr || ! ( *per_fr != *cur_fr) ) {
        errln("ERROR: == failed");
    }
}

// ======= Test various format() methods
if (cur_fr != NULL)
{
    logln("Testing various format() methods");

    double d = -10456.0037;
    int32_t l = 100000000;
    Formattable fD(d);
    Formattable fL(l);

    UnicodeString res1, res2, res3, res4, res5, res6;
    FieldPosition pos1(FieldPosition::DONT_CARE), pos2(FieldPosition::DONT_CARE), pos3(FieldPosition::DONT_CARE), pos4(FieldPosition::DONT_CARE);
    
    res1 = cur_fr->format(d, res1);
    logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1);

    res2 = cur_fr->format(l, res2);
    logln((UnicodeString) "" + (int32_t) l + " formatted to " + res2);

    res3 = cur_fr->format(d, res3, pos1);
    logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res3);

    res4 = cur_fr->format(l, res4, pos2);
    logln((UnicodeString) "" + (int32_t) l + " formatted to " + res4);

    status = U_ZERO_ERROR;
    res5 = cur_fr->format(fD, res5, pos3, status);
    if(U_FAILURE(status)) {
        errln("ERROR: format(Formattable [double]) failed");
    }
    logln((UnicodeString) "" + (int32_t) fD.getDouble() + " formatted to " + res5);

    status = U_ZERO_ERROR;
    res6 = cur_fr->format(fL, res6, pos4, status);
    if(U_FAILURE(status)) {
        errln("ERROR: format(Formattable [long]) failed");
    }
    logln((UnicodeString) "" + fL.getLong() + " formatted to " + res6);
}

// ======= Test parse()
if (fr != NULL)
{
    logln("Testing parse()");

    double d = -10456.0037;
    UnicodeString text("-10,456.0037");
    Formattable result1, result2, result3;
    ParsePosition pos(0), pos01(0);
    fr->parseObject(text, result1, pos);
    if(result1.getType() != Formattable::kDouble && result1.getDouble() != d) {
        errln("ERROR: Roundtrip failed (via parse()) for " + text);
    }
    logln(text + " parsed into " + (int32_t) result1.getDouble());

    fr->parse(text, result2, pos01);
    if(result2.getType() != Formattable::kDouble && result2.getDouble() != d) {
        errln("ERROR: Roundtrip failed (via parse()) for " + text);
    }
    logln(text + " parsed into " + (int32_t) result2.getDouble());

    status = U_ZERO_ERROR;
    fr->parse(text, result3, status);
    if(U_FAILURE(status)) {
        errln("ERROR: parse() failed");
    }
    if(result3.getType() != Formattable::kDouble && result3.getDouble() != d) {
        errln("ERROR: Roundtrip failed (via parse()) for " + text);
    }
    logln(text + " parsed into " + (int32_t) result3.getDouble());
}

// ======= Test getters and setters
if (fr != NULL && def != NULL)
{
    logln("Testing getters and setters");

    int32_t count = 0;
    const Locale *locales = NumberFormat::getAvailableLocales(count);
    logln((UnicodeString) "Got " + count + " locales" );
    for(int32_t i = 0; i < count; i++) {
        UnicodeString name(locales[i].getName(),"");
        logln(name);
    }

    fr->setParseIntegerOnly( def->isParseIntegerOnly() );
    if(fr->isParseIntegerOnly() != def->isParseIntegerOnly() ) {
        errln("ERROR: setParseIntegerOnly() failed");
    }

    fr->setGroupingUsed( def->isGroupingUsed() );
    if(fr->isGroupingUsed() != def->isGroupingUsed() ) {
        errln("ERROR: setGroupingUsed() failed");
    }

    fr->setMaximumIntegerDigits( def->getMaximumIntegerDigits() );
    if(fr->getMaximumIntegerDigits() != def->getMaximumIntegerDigits() ) {
        errln("ERROR: setMaximumIntegerDigits() failed");
    }

    fr->setMinimumIntegerDigits( def->getMinimumIntegerDigits() );
    if(fr->getMinimumIntegerDigits() != def->getMinimumIntegerDigits() ) {
        errln("ERROR: setMinimumIntegerDigits() failed");
    }

    fr->setMaximumFractionDigits( def->getMaximumFractionDigits() );
    if(fr->getMaximumFractionDigits() != def->getMaximumFractionDigits() ) {
        errln("ERROR: setMaximumFractionDigits() failed");
    }

    fr->setMinimumFractionDigits( def->getMinimumFractionDigits() );
    if(fr->getMinimumFractionDigits() != def->getMinimumFractionDigits() ) {
        errln("ERROR: setMinimumFractionDigits() failed");
    }
}

// ======= Test getStaticClassID()

    logln("Testing getStaticClassID()");

    status = U_ZERO_ERROR;
    NumberFormat *test = new DecimalFormat(status);
    if(U_FAILURE(status)) {
        errcheckln(status, "ERROR: Couldn't create a NumberFormat - %s", u_errorName(status));
    }

    if(test->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
        errln("ERROR: getDynamicClassID() didn't return the expected value");
    }

    delete test;
    delete def;
    delete fr;
    delete cur;
    delete cur_fr;
    delete per;
    delete per_fr;
}

#if !UCONFIG_NO_SERVICE

#define SRC_LOC Locale::getFrance()
#define SWAP_LOC Locale::getUS()

class NFTestFactory : public SimpleNumberFormatFactory {
    NumberFormat* currencyStyle;

public:
    NFTestFactory() 
        : SimpleNumberFormatFactory(SRC_LOC, TRUE)
    {
        UErrorCode status = U_ZERO_ERROR;
        currencyStyle = NumberFormat::createInstance(SWAP_LOC, status);
    }

    virtual ~NFTestFactory()
    {
        delete currencyStyle;
    }
    
    virtual NumberFormat* createFormat(const Locale& /* loc */, UNumberFormatStyle formatType)
    {
        if (formatType == UNUM_CURRENCY) {
            return currencyStyle->clone();
        }
        return NULL;
    }

   virtual inline UClassID getDynamicClassID() const
   {
       return (UClassID)&gID;
   }

   static inline UClassID getStaticClassID()
   {
        return (UClassID)&gID;
   }

private:
   static char gID;
};

char NFTestFactory::gID = 0;
#endif

void
IntlTestNumberFormatAPI::testRegistration() 
{
#if !UCONFIG_NO_SERVICE
    UErrorCode status = U_ZERO_ERROR;
    
    LocalPointer<NumberFormat> f0(NumberFormat::createInstance(SWAP_LOC, status));
    LocalPointer<NumberFormat> f1(NumberFormat::createInstance(SRC_LOC, status));
    LocalPointer<NumberFormat> f2(NumberFormat::createCurrencyInstance(SRC_LOC, status));
    URegistryKey key = NumberFormat::registerFactory(new NFTestFactory(), status);
    LocalPointer<NumberFormat> f3(NumberFormat::createCurrencyInstance(SRC_LOC, status));
    LocalPointer<NumberFormat> f3a(NumberFormat::createCurrencyInstance(SRC_LOC, status));
    LocalPointer<NumberFormat> f4(NumberFormat::createInstance(SRC_LOC, status));

    LocalPointer<StringEnumeration> locs(NumberFormat::getAvailableLocales());

    LocalUNumberFormatPointer uf3(unum_open(UNUM_CURRENCY, NULL, 0, SRC_LOC.getName(), NULL, &status));
    LocalUNumberFormatPointer uf4(unum_open(UNUM_DEFAULT, NULL, 0, SRC_LOC.getName(), NULL, &status));

    const UnicodeString* res;
    for (res = locs->snext(status); res; res = locs->snext(status)) {
        logln(*res); // service is still in synch
    }

    NumberFormat::unregister(key, status); // restore for other tests
    LocalPointer<NumberFormat> f5(NumberFormat::createCurrencyInstance(SRC_LOC, status));
    LocalUNumberFormatPointer uf5(unum_open(UNUM_CURRENCY, NULL, 0, SRC_LOC.getName(), NULL, &status));

    if (U_FAILURE(status)) {
        dataerrln("Error creating instanaces.");
        return;
    } else {
        float n = 1234.567f;
        UnicodeString res0, res1, res2, res3, res4, res5;
        UChar ures3[50];
        UChar ures4[50];
        UChar ures5[50];

        f0->format(n, res0);
        f1->format(n, res1);
        f2->format(n, res2);
        f3->format(n, res3);
        f4->format(n, res4);
        f5->format(n, res5);

        unum_formatDouble(uf3.getAlias(), n, ures3, 50, NULL, &status);
        unum_formatDouble(uf4.getAlias(), n, ures4, 50, NULL, &status);
        unum_formatDouble(uf5.getAlias(), n, ures5, 50, NULL, &status);

        logln((UnicodeString)"f0 swap int: " + res0);
        logln((UnicodeString)"f1 src int: " + res1);
        logln((UnicodeString)"f2 src cur: " + res2);
        logln((UnicodeString)"f3 reg cur: " + res3);
        logln((UnicodeString)"f4 reg int: " + res4);
        logln((UnicodeString)"f5 unreg cur: " + res5);
        log("uf3 reg cur: ");
        logln(ures3);
        log("uf4 reg int: ");
        logln(ures4);
        log("uf5 ureg cur: ");
        logln(ures5);

        if (f3.getAlias() == f3a.getAlias()) {
            errln("did not get new instance from service");
            f3a.orphan();
        }
        if (res3 != res0) {
            errln("registered service did not match");
        }
        if (res4 != res1) {
            errln("registered service did not inherit");
        }
        if (res5 != res2) {
            errln("unregistered service did not match original");
        }

        if (res0 != ures3) {
            errln("registered service did not match / unum");
        }
        if (res1 != ures4) {
            errln("registered service did not inherit / unum");
        }
        if (res2 != ures5) {
            errln("unregistered service did not match original / unum");
        }
    }

    for (res = locs->snext(status); res; res = locs->snext(status)) {
        errln(*res); // service should be out of synch
    }

    locs->reset(status); // now in synch again, we hope
    for (res = locs->snext(status); res; res = locs->snext(status)) {
        logln(*res);
    }
#endif
}


#endif /* #if !UCONFIG_NO_FORMATTING */
