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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "selfmts.h"
#include "cmemory.h"
#include "unicode/selfmt.h"

#define SIMPLE_PATTERN_STRING                                                    "feminine {feminineVerbValue} other{otherVerbValue}"


#define SELECT_PATTERN_DATA 4
#define SELECT_SYNTAX_DATA 10
#define EXP_FORMAT_RESULT_DATA 12
#define NUM_OF_FORMAT_ARGS 3

#define VERBOSE_INT(x) UPRV_BLOCK_MACRO_BEGIN { \
    logln("%s:%d:  int %s=%d\n", __FILE__, __LINE__, #x, (x)); \
} UPRV_BLOCK_MACRO_END
#define VERBOSE_USTRING(text) UPRV_BLOCK_MACRO_BEGIN { \
    logln("%s:%d: UnicodeString %s(%d) = ", __FILE__, __LINE__, #text, text.length()); \
    logln(UnicodeString(" \"")+text+UnicodeString("\";")); \
} UPRV_BLOCK_MACRO_END


void SelectFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    if (exec) logln("TestSuite SelectFormat");
    switch (index) {
        TESTCASE(0, selectFormatAPITest);
        TESTCASE(1, selectFormatUnitTest);
        default: name = "";
            break;
    }
}

/**
 * Unit tests of SelectFormat class.
 */
void SelectFormatTest::selectFormatUnitTest(/*char *par*/)
{
  const UnicodeString SIMPLE_PATTERN(SIMPLE_PATTERN_STRING); /* Don't static init this! */

    UnicodeString patternTestData[SELECT_PATTERN_DATA] = {
        UNICODE_STRING_SIMPLE("fem {femValue} other{even}"),
        UNICODE_STRING_SIMPLE("other{odd or even}"),
        UNICODE_STRING_SIMPLE("odd{The number {0, number, integer} is odd.}other{The number {0, number, integer} is even.}"),
        UNICODE_STRING_SIMPLE("odd{The number {1} is odd}other{The number {1} is even}"),
    };

    UnicodeString formatArgs[NUM_OF_FORMAT_ARGS] = {
        UNICODE_STRING_SIMPLE("fem"),
        UNICODE_STRING_SIMPLE("other"),
        UNICODE_STRING_SIMPLE("odd")
    };

    UnicodeString expFormatResult[][NUM_OF_FORMAT_ARGS] = {
        {
            UNICODE_STRING_SIMPLE("femValue"),
            UNICODE_STRING_SIMPLE("even"),
            UNICODE_STRING_SIMPLE("even")
        },
        {
            UNICODE_STRING_SIMPLE("odd or even"),
            UNICODE_STRING_SIMPLE("odd or even"),
            UNICODE_STRING_SIMPLE("odd or even"),
        },
        {
            UNICODE_STRING_SIMPLE("The number {0, number, integer} is even."),
            UNICODE_STRING_SIMPLE("The number {0, number, integer} is even."),
            UNICODE_STRING_SIMPLE("The number {0, number, integer} is odd."),
        },
        {
            UNICODE_STRING_SIMPLE("The number {1} is even"),
            UNICODE_STRING_SIMPLE("The number {1} is even"),
            UNICODE_STRING_SIMPLE("The number {1} is odd"),
        }
    };

    UnicodeString checkSyntaxData[SELECT_SYNTAX_DATA] = {
        UNICODE_STRING_SIMPLE("odd{foo}"),
        UNICODE_STRING_SIMPLE("*odd{foo} other{bar}"),
        UNICODE_STRING_SIMPLE("odd{foo},other{bar}"),
        UNICODE_STRING_SIMPLE("od d{foo} other{bar}"),
        UNICODE_STRING_SIMPLE("odd{foo}{foobar}other{foo}"),
        UNICODE_STRING_SIMPLE("odd{foo1}other{foo2}}"),  
        UNICODE_STRING_SIMPLE("odd{foo1}other{{foo2}"),  
        UNICODE_STRING_SIMPLE("odd{fo{o1}other{foo2}}")
    };

    UErrorCode status = U_ZERO_ERROR;
    VERBOSE_USTRING(SIMPLE_PATTERN);
    SelectFormat* selFmt = new SelectFormat( SIMPLE_PATTERN , status); 
    if (U_FAILURE(status)) {
        dataerrln("ERROR: SelectFormat Unit Test constructor failed in unit tests.- exitting");
        return;
    }

    // ======= Test SelectFormat pattern syntax.
    logln("SelectFormat Unit Test : Testing SelectFormat pattern syntax.");
    for (int32_t i=0; i<SELECT_SYNTAX_DATA; ++i) {
        status = U_ZERO_ERROR;
        VERBOSE_INT(i);
        VERBOSE_USTRING(checkSyntaxData[i]);
        selFmt->applyPattern(checkSyntaxData[i], status);
        if (U_SUCCESS(status)){
            errln("\nERROR: Unexpected result - SelectFormat Unit Test failed to detect syntax error with pattern: "+checkSyntaxData[i]);
        }
    }

    // ICU 4.8 does not check for duplicate keywords any more.
    status = U_ZERO_ERROR;
    selFmt->applyPattern("odd{foo} odd{bar} other{foobar}", status);
    FieldPosition format_ignore(FieldPosition::DONT_CARE);
    UnicodeString format_result;
    selFmt->format(UnicodeString("odd"), format_result, format_ignore, status);
    assertEquals("should use first occurrence of the 'odd' keyword", "foo", format_result);
    format_result.remove();
    selFmt->applyPattern("odd{foo} other{bar} other{foobar}", status);
    selFmt->format(UnicodeString("other"), format_result, format_ignore, status);
    assertEquals("should use first occurrence of the 'other' keyword", "bar", format_result);

    delete selFmt;
    selFmt = NULL;

    logln("SelectFormat Unit Test : Creating format object for Testing applying various patterns");
    status = U_ZERO_ERROR;
    selFmt = new SelectFormat( SIMPLE_PATTERN , status); 
    //SelectFormat* selFmt1 = new SelectFormat( SIMPLE_PATTERN , status); 
    if (U_FAILURE(status)) {
        errln("ERROR: SelectFormat Unit Test constructor failed in unit tests.- exitting");
        return;
    }

    // ======= Test applying and formatting with various pattern
    logln("SelectFormat Unit test: Testing  applyPattern() and format() ...");
    UnicodeString result;
    FieldPosition ignore(FieldPosition::DONT_CARE);

    for(int32_t i=0; i<SELECT_PATTERN_DATA; ++i) {
        status = U_ZERO_ERROR;
        selFmt->applyPattern(patternTestData[i], status);
        if (U_FAILURE(status)) {
            errln("ERROR: SelectFormat Unit Test failed to apply pattern- "+patternTestData[i] );
            continue;
        }

        //Format with the keyword array
        for(int32_t j=0; j<3; j++) {
            result.remove();
            selFmt->format( formatArgs[j], result , ignore , status);
            if (U_FAILURE(status)) {
                errln("ERROR: SelectFormat Unit test failed in format() with argument: "+ formatArgs[j] + " and error is " + u_errorName(status) );
            }else{
                if( result != expFormatResult[i][j] ){
                    errln("ERROR: SelectFormat Unit test failed in format() with unexpected result\n  with argument: "+ formatArgs[j] + "\n result obtained: " + result + "\n and expected is: " + expFormatResult[i][j] );
                }
            }
        }
    }

    //Test with an invalid keyword
    // one which contains Pattern_Syntax or Pattern_White_Space.
    logln("SelectFormat Unit test: Testing  format() with keyword method and with invalid keywords...");
    status = U_ZERO_ERROR;
    result.remove();
    UnicodeString keywords[] = {
        "9Keyword-_",
        "-Keyword-_",
        "_Keyword-_",
        "\\u00E9Keyword-_",
        "Key word-_",
        " Keyword-_",
        "Key*word-_",
        "*Keyword-_"
    };

    delete selFmt;
    selFmt = NULL;

    selFmt = new SelectFormat( SIMPLE_PATTERN , status); 
    for (int32_t i = 0; i < UPRV_LENGTHOF(keywords); i++ ){
        status = U_ZERO_ERROR;
        selFmt->format( keywords[i], result , ignore , status);
        if (!U_FAILURE(status)) {
            errln("ERROR: SelectFormat Unit test failed in format() with keyWord and with an invalid keyword as : "+
                  keywords[i]+" ("+u_errorName(status)+")");
        }
    }

    delete selFmt;
}

/**
 * Test various generic API methods of SelectFormat for Basic API usage.
 * This is to make sure the API test coverage is 100% .
 */
void SelectFormatTest::selectFormatAPITest(/*char *par*/)
{
  const UnicodeString SIMPLE_PATTERN(SIMPLE_PATTERN_STRING); /* Don't static init this! */
    int numOfConstructors =3;
    UErrorCode status[3];
    SelectFormat* selFmt[3] = { NULL, NULL, NULL };

    // ========= Test constructors
    logln("SelectFormat API test: Testing SelectFormat constructors ...");
    for (int32_t i=0; i< numOfConstructors; ++i) {
        status[i] = U_ZERO_ERROR;
    }

    selFmt[0]= new SelectFormat(SIMPLE_PATTERN, status[0]);
    if ( U_FAILURE(status[0]) ) {
      errln("ERROR: SelectFormat API test constructor with pattern and status failed! with %s\n", u_errorName(status[0]));
        return;
    }

    // =========== Test copy constructor
    logln("SelectFormat API test: Testing copy constructor and == operator ...");
    SelectFormat fmt = *selFmt[0];
    SelectFormat* dupPFmt = new SelectFormat(fmt);
    if ((*selFmt[0]) != (*dupPFmt)) {
        errln("ERROR: SelectFormat API test Failed in copy constructor or == operator!");
    }
    delete dupPFmt;
    
    // ======= Test clone && == operator.
    logln("SelectFormat API test: Testing clone and == operator ...");
    if ( U_SUCCESS(status[0])  ) {
        selFmt[1] = selFmt[0]->clone();
        if (selFmt[1]!=NULL) {
            if ( *selFmt[1] != *selFmt[0] ) {
                errln("ERROR: SelectFormat API test clone test failed!");
            }
        } else {
          errln("ERROR: SelectFormat API test clone test failed with NULL!");
          return;
        }
    } else {
      errln("ERROR: could not create [0]: %s\n", u_errorName(status[0]));
      return;
    }

    // ======= Test assignment operator && == operator.
    logln("SelectFormat API test: Testing assignment operator and == operator ...");
    selFmt[2]= new SelectFormat(SIMPLE_PATTERN, status[2]);
    if ( U_SUCCESS(status[2]) ) {
        *selFmt[1] = *selFmt[2];
        if (selFmt[1]!=NULL) {
            if ( (*selFmt[1] != *selFmt[2]) ) {
                errln("ERROR: SelectFormat API test assignment operator test failed!");
            }
        }
        delete selFmt[1];
    }
    else {
         errln("ERROR: SelectFormat constructor failed in assignment operator!");
    }
    delete selFmt[0];
    delete selFmt[2];

    // ======= Test getStaticClassID() and getStaticClassID()
    logln("SelectFormat API test: Testing getStaticClassID() and getStaticClassID() ...");
    UErrorCode status1 = U_ZERO_ERROR;
    SelectFormat* selFmt1 = new SelectFormat( SIMPLE_PATTERN , status1); 
    if( U_FAILURE(status1)) {
        errln("ERROR: SelectFormat constructor failed in staticClassID test! Exitting");
        return;
    }

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

    // ======= Test applyPattern() and toPattern()
    logln("SelectFormat API test: Testing applyPattern() and toPattern() ...");
    UnicodeString pattern = UnicodeString("masculine{masculineVerbValue} other{otherVerbValue}");
    status1 = U_ZERO_ERROR;
    selFmt1->applyPattern( pattern, status1);
    if (U_FAILURE(status1)) {
        errln("ERROR: SelectFormat API test failed in applyPattern() with pattern: "+ pattern);
    }else{
        UnicodeString checkPattern;
        selFmt1->toPattern( checkPattern);
        if( checkPattern != pattern ){
            errln("ERROR: SelectFormat API test failed in toPattern() with unexpected result with pattern: "+ pattern);
        }
    }

    // ======= Test different format() methods 
    logln("SelectFormat API test: Testing  format() with keyword method ...");
    status1 = U_ZERO_ERROR;
    UnicodeString result;
    FieldPosition ignore(FieldPosition::DONT_CARE);
    UnicodeString keyWord = UnicodeString("masculine");

    selFmt1->format( keyWord, result , ignore , status1);
    if (U_FAILURE(status1)) {
        errln("ERROR: SelectFormat API test failed in format() with keyWord: "+ keyWord);
    }else{
        UnicodeString expected=UnicodeString("masculineVerbValue");
        if( result != expected ){
            errln("ERROR: SelectFormat API test failed in format() with unexpected result with keyWord: "+ keyWord);
        }
    }
    
    logln("SelectFormat API test: Testing  format() with Formattable obj method ...");
    status1 = U_ZERO_ERROR;
    result.remove();
    UnicodeString result1;
    Formattable testArgs = Formattable("other");
    selFmt1->format( testArgs, result1 , ignore , status1);
    if (U_FAILURE(status1)) {
        errln("ERROR: SelectFormat API test failed in format() with Formattable");
    }else{
        UnicodeString expected=UnicodeString("otherVerbValue");
        if( result1 != expected ){
            errln("ERROR: SelectFormat API test failed in format() with unexpected result with Formattable");
        }
    }


    delete selFmt1;
}
#endif /* #if !UCONFIG_NO_FORMATTING */
