// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2001-2010, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/
/************************************************************************
*   This test program is intended for testing Replaceable class.
*
*   Date        Name        Description
*   11/28/2001  hshih       Ported back from Java.
* 
************************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_TRANSLITERATION

#include "ittrans.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "unicode/rep.h"
#include "reptest.h"

//---------------------------------------------
// runIndexedTest
//---------------------------------------------

    /**
     * This is a test class that simulates styled text.
     * It associates a style number (0..65535) with each character,
     * and maintains that style in the normal fashion:
     * When setting text from raw string or characters,<br>
     * Set the styles to the style of the first character replaced.<br>
     * If no characters are replaced, use the style of the previous character.<br>
     * If at start, use the following character<br>
     * Otherwise use NO_STYLE.
     */
class TestReplaceable : public Replaceable {
    UnicodeString chars;
    UnicodeString styles;
    
    static const UChar NO_STYLE;

    static const UChar NO_STYLE_MARK;

    /**
     * The address of this static class variable serves as this class's ID
     * for ICU "poor man's RTTI".
     */
    static const char fgClassID;

public:    
    TestReplaceable (const UnicodeString& text, 
                     const UnicodeString& newStyles) {
        chars = text;
        UnicodeString s;
        for (int i = 0; i < text.length(); ++i) {
            if (i < newStyles.length()) {
                s.append(newStyles.charAt(i));
            } else {
                if (text.charAt(i) == NO_STYLE_MARK) {
                    s.append(NO_STYLE);
                } else {
                    s.append((UChar)(i + 0x0031));
                }
            }
        }
        this->styles = s;
    }

    virtual Replaceable *clone() const {
        return new TestReplaceable(chars, styles);
    }

    ~TestReplaceable(void) {}

    UnicodeString getStyles() {
        return styles;
    }
    
    UnicodeString toString() {
        UnicodeString s = chars;
        s.append("{");
        s.append(styles);
        s.append("}");
        return s;
    }

    void extractBetween(int32_t start, int32_t limit, UnicodeString& result) const {
        chars.extractBetween(start, limit, result);
    }

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @draft ICU 2.2
     */
    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @draft ICU 2.2
     */
    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }

protected:
    virtual int32_t getLength() const {
        return chars.length();
    }

    virtual UChar getCharAt(int32_t offset) const{
        return chars.charAt(offset);
    }

    virtual UChar32 getChar32At(int32_t offset) const{
        return chars.char32At(offset);
    }

    void fixStyles(int32_t start, int32_t limit, int32_t newLen) {
        UChar newStyle = NO_STYLE;
        if (start != limit && styles.charAt(start) != NO_STYLE) {
            newStyle = styles.charAt(start);
        } else if (start > 0 && getCharAt(start-1) != NO_STYLE_MARK) {
            newStyle = styles.charAt(start-1);
        } else if (limit < styles.length()) {
            newStyle = styles.charAt(limit);
        }
        // dumb implementation for now.
        UnicodeString s;
        for (int i = 0; i < newLen; ++i) {
            // this doesn't really handle an embedded NO_STYLE_MARK
            // in the middle of a long run of characters right -- but
            // that case shouldn't happen anyway
            if (getCharAt(start+i) == NO_STYLE_MARK) {
                s.append(NO_STYLE);
            } else {
                s.append(newStyle);
            }
        }
        styles.replaceBetween(start, limit, s);
    }

    virtual void handleReplaceBetween(int32_t start, int32_t limit, const UnicodeString& text) {
        UnicodeString s;
        this->extractBetween(start, limit, s);
        if (s == text) return; // NO ACTION!
        this->chars.replaceBetween(start, limit, text);
        fixStyles(start, limit, text.length());
    }
    

    virtual void copy(int32_t start, int32_t limit, int32_t dest) {
        chars.copy(start, limit, dest);
        styles.copy(start, limit, dest);
    }
};

const char TestReplaceable::fgClassID=0;

const UChar TestReplaceable::NO_STYLE  = 0x005F;

const UChar TestReplaceable::NO_STYLE_MARK = 0xFFFF;

void
ReplaceableTest::runIndexedTest(int32_t index, UBool exec,
                                      const char* &name, char* /*par*/) {
    switch (index) {
        TESTCASE(0,TestReplaceableClass);
        default: name = ""; break;
    }
}

/*
 * Dummy Replaceable implementation for better API/code coverage.
 */
class NoopReplaceable : public Replaceable {
public:
    virtual int32_t getLength() const {
        return 0;
    }

    virtual UChar getCharAt(int32_t /*offset*/) const{
        return 0xffff;
    }

    virtual UChar32 getChar32At(int32_t /*offset*/) const{
        return 0xffff;
    }

    void extractBetween(int32_t /*start*/, int32_t /*limit*/, UnicodeString& result) const {
        result.remove();
    }

    virtual void handleReplaceBetween(int32_t /*start*/, int32_t /*limit*/, const UnicodeString &/*text*/) {
        /* do nothing */
    }

    virtual void copy(int32_t /*start*/, int32_t /*limit*/, int32_t /*dest*/) {
        /* do nothing */
    }

    static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; }
    virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); }

private:
    static const char fgClassID;
};

const char NoopReplaceable::fgClassID=0;

void ReplaceableTest::TestReplaceableClass(void) {
    UChar rawTestArray[][6] = {
        {0x0041, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // ABCD
        {0x0061, 0x0062, 0x0063, 0x0064, 0x00DF, 0x0000}, // abcd\u00DF
        {0x0061, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // aBCD
        {0x0041, 0x0300, 0x0045, 0x0300, 0x0000, 0x0000}, // A\u0300E\u0300
        {0x00C0, 0x00C8, 0x0000, 0x0000, 0x0000, 0x0000}, // \u00C0\u00C8
        {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
        {0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000}, /* "wxyz" */
        {0x0077, 0x0078, 0x0079, 0x007A, 0x0075, 0x0000}, /* "wxyzu" */
        {0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000}, /* "xyz" */
        {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */
        {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
        {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */
    };
    check("Lower", rawTestArray[0], "1234");
    check("Upper", rawTestArray[1], "123455"); // must map 00DF to SS
    check("Title", rawTestArray[2], "1234");
    check("NFC",   rawTestArray[3], "13");
    check("NFD",   rawTestArray[4], "1122");
    check("*(x) > A $1 B", rawTestArray[5], "11223");
    check("*(x)(y) > A $2 B $1 C $2 D", rawTestArray[6], "113322334");
    check("*(x)(y)(z) > A $3 B $2 C $1 D", rawTestArray[7], "114433225");
    // Disabled for 2.4.  TODO Revisit in 2.6 or later.
    //check("*x > a", rawTestArray[8], "223"); // expect "123"?
    //check("*x > a", rawTestArray[9], "113"); // expect "123"?
    //check("*x > a", rawTestArray[10], "_33"); // expect "_23"?
    //check("*(x) > A $1 B", rawTestArray[11], "__223");

    // improve API/code coverage
    NoopReplaceable noop;
    Replaceable *p;
    if((p=noop.clone())!=NULL) {
        errln("Replaceable::clone() does not return NULL");
        delete p;
    }

    if(!noop.hasMetaData()) {
        errln("Replaceable::hasMetaData() does not return TRUE");
    }

    // try to call the compiler-provided
    // UMemory/UObject/Replaceable assignment operators
    NoopReplaceable noop2;
    noop2=noop;
    if((p=noop2.clone())!=NULL) {
        errln("noop2.Replaceable::clone() does not return NULL");
        delete p;
    }

    // try to call the compiler-provided
    // UMemory/UObject/Replaceable copy constructors
    NoopReplaceable noop3(noop);
    if((p=noop3.clone())!=NULL) {
        errln("noop3.Replaceable::clone() does not return NULL");
        delete p;
    }
}

void ReplaceableTest::check(const UnicodeString& transliteratorName, 
                            const UnicodeString& test, 
                            const UnicodeString& shouldProduceStyles) 
{
    UErrorCode status = U_ZERO_ERROR;
    TestReplaceable *tr = new TestReplaceable(test, "");
    UnicodeString expectedStyles = shouldProduceStyles;
    UnicodeString original = tr->toString();

    Transliterator* t;
    if (transliteratorName.charAt(0) == 0x2A /*'*'*/) {
        UnicodeString rules(transliteratorName);
        rules.remove(0,1);
        UParseError pe;
        t = Transliterator::createFromRules("test", rules, UTRANS_FORWARD,
                                            pe, status);

        // test clone()
        TestReplaceable *tr2 = (TestReplaceable *)tr->clone();
        if(tr2 != NULL) {
            delete tr;
            tr = tr2;
        }
    } else {
        t = Transliterator::createInstance(transliteratorName, UTRANS_FORWARD, status);
    }
    if (U_FAILURE(status)) {
        dataerrln("FAIL: failed to create the " + transliteratorName + " transliterator");
        delete tr;
        return;
    }
    t->transliterate(*tr);
    UnicodeString newStyles = tr->getStyles();
    if (newStyles != expectedStyles) {
        errln("FAIL Styles: " + transliteratorName + "{" + original + "} => "
            + tr->toString() + "; should be {" + expectedStyles + "}!");
    } else {
        log("OK: ");
        log(transliteratorName);
        log("(");
        log(original);
        log(") => ");
        logln(tr->toString());
    }
    delete tr;
    delete t;
}

#endif /* #if !UCONFIG_NO_TRANSLITERATION */
