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

#include "unicode/utypes.h"

#if !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_REGULAR_EXPRESSIONS && !UCONFIG_NO_FORMATTING

#include "intltest.h"

#include "unicode/rbbi.h"
#include "unicode/regex.h"
#include "unicode/uniset.h"
#include "unicode/unistr.h"
#include "unicode/uobject.h"

#include "simplethread.h"
#include "ucbuf.h"
#include "uhash.h"
#include "uvector.h"

// RBBI Monkey Test. Run break iterators against randomly generated strings, compare results with
//                   an independent reference implementation.
//
//         The monkey test can be run with parameters, e.g.
//              intltest rbbi/RBBIMonkeyTest@loop=-1,rules=word.txt
//         will run word break testing in an infinite loop.
//         Summary of options
//               rules=name             Test against the named reference rule file.
//                                     Files are found in source/test/testdata/break_rules
//               loop=nnn              Loop nnn times. -1 for no limit. loop of 1 is useful for debugging.
//               seed=nnnn             Random number generator seed. Allows recreation of a failure.
//                                     Error messages include the necessary seed value.
//               verbose               Display details of a failure. Useful for debugging. Use with loop=1.
//               expansions            Debug option, show expansions of rules and sets.
//
//  TODO:
//     Develop a tailoring format.
//     Hook to old tests that use monkey impl to get expected data.
//     Remove old tests.

class BreakRules;       // Forward declaration
class RBBIMonkeyImpl;

/**
 * Test the RuleBasedBreakIterator class giving different rules
 */
class RBBIMonkeyTest: public IntlTest {
  public:
    RBBIMonkeyTest();
    virtual ~RBBIMonkeyTest();

    void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL );
    void testMonkey();


  private:
    const char *fParams;                  // Copy of user parameters passed in from IntlTest.


    void testRules(const char *ruleFile);
    static UBool getIntParam(UnicodeString name, UnicodeString &params, int64_t &val, UErrorCode &status);
    static UBool getStringParam(UnicodeString name, UnicodeString &params, CharString &dest, UErrorCode &status);
    static UBool getBoolParam(UnicodeString name, UnicodeString &params, UBool &dest, UErrorCode &status);

};

// The following classes are internal to the RBBI Monkey Test implementation.



//  class CharClass    Represents a single character class from the source break rules.
//                     Inherits from UObject because instances are adopted by UHashtable, which ultimately
//                     deletes them using hash's object deleter function.

class CharClass: public UObject {
  public:
    UnicodeString                fName;
    UnicodeString                fOriginalDef;    // set definition as it appeared in user supplied rules.
    UnicodeString                fExpandedDef;    // set definition with any embedded named sets replaced by their defs, recursively.
    LocalPointer<const UnicodeSet>     fSet;
    CharClass(const UnicodeString &name, const UnicodeString &originalDef, const UnicodeString &expandedDef, const UnicodeSet *set) :
            fName(name), fOriginalDef(originalDef), fExpandedDef(expandedDef), fSet(set) {}
};


// class BreakRule    represents a single rule from a set of break rules.
//                    Each rule has the set definitions expanded, and
//                    is compiled to a regular expression.

class BreakRule: public UObject {
  public:
    BreakRule();
    ~BreakRule();
    UnicodeString    fName;                            // Name of the rule.
    UnicodeString    fRule;                            // Rule expression, excluding the name, as written in user source.
    UnicodeString    fExpandedRule;                    // Rule expression after expanding the set definitions.
    LocalPointer<RegexMatcher>  fRuleMatcher;          // Regular expression that matches the rule.
    bool             fInitialMatchOnly = false;        // True if rule begins with '^', meaning no chaining.
};


// class BreakRules    represents a complete set of break rules, possibly tailored,
//                     compiled from testdata break rules.

class BreakRules: public UObject {
  public:
    BreakRules(RBBIMonkeyImpl *monkeyImpl, UErrorCode &status);
    ~BreakRules();

    void compileRules(UCHARBUF *rules, UErrorCode &status);

    const CharClass *getClassForChar(UChar32 c, int32_t *iter=NULL) const;


    RBBIMonkeyImpl    *fMonkeyImpl;        // Pointer back to the owning MonkeyImpl instance.
    icu::UVector       fBreakRules;        // Contents are of type (BreakRule *).

    LocalUHashtablePointer fCharClasses;   // Key is set name (UnicodeString).
                                           // Value is (CharClass *)
    LocalPointer<UVector>  fCharClassList; // Char Classes, same contents as fCharClasses values,
                                           //   but in a vector so they can be accessed by index.
    UnicodeSet         fDictionarySet;     // Dictionary set, empty if none is defined.
    Locale             fLocale;
    UBreakIteratorType fType;

    CharClass *addCharClass(const UnicodeString &name, const UnicodeString &def, UErrorCode &status);
    void addRule(const UnicodeString &name, const UnicodeString &def, UErrorCode &status);
    bool setKeywordParameter(const UnicodeString &keyword, const UnicodeString &value, UErrorCode &status);
    RuleBasedBreakIterator *createICUBreakIterator(UErrorCode &status);

    LocalPointer<RegexMatcher> fSetRefsMatcher;
    LocalPointer<RegexMatcher> fCommentsMatcher;
    LocalPointer<RegexMatcher> fClassDefMatcher;
    LocalPointer<RegexMatcher> fRuleDefMatcher;
};


// class MonkeyTestData    represents a randomly synthesized test data string together
//                         with the expected break positions obtained by applying
//                         the test break rules.

class MonkeyTestData: public UObject {
  public:
    MonkeyTestData() {}
    ~MonkeyTestData() {}
    void set(BreakRules *rules, IntlTest::icu_rand &rand, UErrorCode &status);
    void clearActualBreaks();
    void dump(int32_t around = -1) const;

    uint32_t               fRandomSeed;        // The initial seed value from the random number genererator.
    const BreakRules      *fBkRules;           // The break rules used to generate this data.
    UnicodeString          fString;            // The text.
    UnicodeString          fExpectedBreaks;    // Breaks as found by the reference rules.
                                               //     Parallel to fString. Non-zero if break preceding.
    UnicodeString          fActualBreaks;      // Breaks as found by ICU break iterator.
    UnicodeString          fRuleForPosition;   // Index into BreakRules.fBreakRules of rule that applied at each position.
                                               // Also parallel to fString.
    UnicodeString          f2ndRuleForPos;     // As above. A 2nd rule applies when the preceding rule
                                               //   didn't cause a break, and a subsequent rule match starts
                                               //   on the last code point of the preceding match.

};




// class RBBIMonkeyImpl     holds (some indirectly) everything associated with running a monkey
//                          test for one set of break rules.
//
//                          When running RBBIMonkeyTest with multiple threads, there is a 1:1 correspondence
//                          between instances of RBBIMonkeyImpl and threads.
//
class RBBIMonkeyImpl: public UObject {
  public:
    RBBIMonkeyImpl(UErrorCode &status);
    ~RBBIMonkeyImpl();

    void setup(const char *ruleFileName, UErrorCode &status);

    void startTest();
    void runTest();
    void join();

    LocalUCHARBUFPointer                 fRuleCharBuffer;         // source file contents of the reference rules.
    LocalPointer<BreakRules>             fRuleSet;
    LocalPointer<RuleBasedBreakIterator> fBI;
    LocalPointer<MonkeyTestData>         fTestData;
    IntlTest::icu_rand                   fRandomGenerator;
    const char                          *fRuleFileName;
    UBool                                fVerbose;                 // True to do long dump of failing data.
    int32_t                              fLoopCount;

    UBool                                fDumpExpansions;          // Debug flag to output epananded form of rules and sets.

    enum CheckDirection {
        FORWARD = 1,
        REVERSE = 2
    };
    void clearActualBreaks();
    void testForwards(UErrorCode &status);
    void testPrevious(UErrorCode &status);
    void testFollowing(UErrorCode &status);
    void testPreceding(UErrorCode &status);
    void testIsBoundary(UErrorCode &status);
    void testIsBoundaryRandom(UErrorCode &status);
    void checkResults(const char *msg, CheckDirection dir, UErrorCode &status);

    class RBBIMonkeyThread: public SimpleThread {
      private:
        RBBIMonkeyImpl *fMonkeyImpl;
      public:
        RBBIMonkeyThread(RBBIMonkeyImpl *impl) : fMonkeyImpl(impl) {}
        void run() U_OVERRIDE { fMonkeyImpl->runTest(); }
    };
  private:
    void openBreakRules(const char *fileName, UErrorCode &status);
    RBBIMonkeyThread fThread;

};

#endif /* !UCONFIG_NO_BREAK_ITERATION && !UCONFIG_NO_REGULAR_EXPRESSIONS && !UCONFIG_NO_FORMATTING */

#endif  //  RBBIMONKEYTEST_H
