// Copyright (C) 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"

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 assignmet, 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_
