// Copyright (C) 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 (NumberFormat*)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));

    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 instnaces.");
        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);
    }

    delete locs;
#endif
}


#endif /* #if !UCONFIG_NO_FORMATTING */
