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

#ifndef _DATADRIVENNUMBERFORMATTESTSUITE_H__
#define _DATADRIVENNUMBERFORMATTESTSUITE_H__

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/uobject.h"
#include "unicode/unistr.h"
#include "numberformattesttuple.h"
#include "intltest.h"
#include "cmemory.h"

struct UCHARBUF;
class IntlTest;

/**
 * Performs various in-depth test on NumberFormat
 **/
class DataDrivenNumberFormatTestSuite : public IntlTest {

 public:
     DataDrivenNumberFormatTestSuite() {
         for (int32_t i = 0; i < UPRV_LENGTHOF(fPreviousFormatters); ++i) {
             fPreviousFormatters[i] = NULL;
         }
     }

     /**
      * Runs the data driven test suite.
      *
      * @param fileName is the name of the file in the source/test/testdata.
      *  This should be just a filename such as "numberformattest.txt"
      * @param runAllTests If TRUE, runs every test in fileName. if FALSE,
      *  skips the tests that are known to break for ICU4C.
      */
     void run(const char *fileName, UBool runAllTests);
     virtual ~DataDrivenNumberFormatTestSuite();
 protected:
    /**
     * Subclasses override this method to test formatting numbers.
     * Subclasses must not override both isFormatPass methods.
     * @param tuple the test data for current test. The format method can
     *   assume that the format and output fields are populated.
     * @param appendErrorMessage any message describing failures appended
     *   here.
     * @param status any error returned here.
     * @return TRUE if test passed or FALSE if test failed.
     */
    virtual UBool isFormatPass(
            const NumberFormatTestTuple &tuple,
            UnicodeString &appendErrorMessage,
            UErrorCode &status);

    
    /**
     * Subclasses override this method to test formatting numbers.
     * Along with copy and assignment operators.
     * @param tuple the test data for current test. The format method can
     *   assume that the format and output fields are populated.
     * @param somePreviousFormatter A pointer to a previous formatter
     *  that the test framework owns. This formatter changes as tests
     *  are run. Subclasses should initialize a formatter and assign
     *  the newly initialized formatter to this formatter. In this way,
     *  assignment gets tested with multiple previous states.
     * @param appendErrorMessage any message describing failures appended
     *   here.
     * @param status any error returned here.
     * @return TRUE if test passed or FALSE if test failed.
     */
    virtual UBool isFormatPass(
            const NumberFormatTestTuple &tuple,
            UObject *somePreviousFormatter,
            UnicodeString &appendErrorMessage,
            UErrorCode &status);
    /**
     * If subclass is testing formatting with copy and assignment, it
     * needs to override this method to return a newly allocated formatter.
     */
    virtual UObject *newFormatter(UErrorCode &status);

    /**
     * Tests toPattern method.
     */
    virtual UBool isToPatternPass(
            const NumberFormatTestTuple &tuple,
            UnicodeString &appendErrorMessage,
            UErrorCode &status);
    /**
     * Test parsing.
     */
    virtual UBool isParsePass(
            const NumberFormatTestTuple &tuple,
            UnicodeString &appendErrorMessage,
            UErrorCode &status);

    /**
     * Test parsing with currency.
     */
    virtual UBool isParseCurrencyPass(
            const NumberFormatTestTuple &tuple,
            UnicodeString &appendErrorMessage,
            UErrorCode &status);

    /**
     * Test plural selection.
     */
    virtual UBool isSelectPass(
            const NumberFormatTestTuple &tuple,
            UnicodeString &appendErrorMessage,
            UErrorCode &status);
 private:
    UnicodeString fFileLine;
    int32_t fFileLineNumber;
    UnicodeString fFileTestName;
    NumberFormatTestTuple fTuple;
    int32_t fFormatTestNumber;
    UObject *fPreviousFormatters[13];

    void setTupleField(UErrorCode &);
    int32_t splitBy(
            UnicodeString *columnValues,
            int32_t columnValueCount,
            UChar delimiter);
    void showError(const char *message);
    void showFailure(const UnicodeString &message);
    void showLineInfo();
    UBool breaksC();
    UBool readLine(UCHARBUF *f, UErrorCode &);
    UBool isPass(
            const NumberFormatTestTuple &tuple,
            UnicodeString &appendErrorMessage,
            UErrorCode &status);
};
#endif /* !UCONFIG_NO_FORMATTING */
#endif // _DATADRIVENNUMBERFORMATTESTSUITE_
