/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-1999, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

#ifndef _COLL
#include "unicode/coll.h"
#endif

#ifndef _TBLCOLL
#include "unicode/tblcoll.h"
#endif

#ifndef _UNISTR
#include "unicode/unistr.h"
#endif

#ifndef _SORTKEY
#include "unicode/sortkey.h"
#endif

#ifndef _ITERCOLL
#include "itercoll.h"
#endif

#define ARRAY_LENGTH(array) (sizeof array / sizeof array[0])

static UErrorCode status = U_ZERO_ERROR;

const UnicodeString CollationIteratorTest::test1 = "What subset of all possible test cases?";
const UnicodeString CollationIteratorTest::test2 = "has the highest probability of detecting";

CollationIteratorTest::CollationIteratorTest()
{
    en_us = (RuleBasedCollator *)Collator::createInstance(Locale::US, status);
}

CollationIteratorTest::~CollationIteratorTest()
{
    delete en_us;
}

/**
 * Test for CollationElementIterator.previous()
 *
 * @bug 4108758 - Make sure it works with contracting characters
 * 
 */
void CollationIteratorTest::TestPrevious(char *par)
{
    UErrorCode status = U_ZERO_ERROR;
    CollationElementIterator *iter = en_us->createCollationElementIterator(test1);

    // A basic test to see if it's working at all
    backAndForth(*iter);
    delete iter;

    // Test with a contracting character sequence
    UnicodeString source;
    RuleBasedCollator *c1 = NULL;
    c1 = new RuleBasedCollator(
        "< a,A < b,B < c,C, d,D < z,Z < ch,cH,Ch,CH", status);

    if (c1 == NULL || U_FAILURE(status))
    {
        errln("Couldn't create a RuleBasedCollator with a contracting sequence.");
        delete c1;
        return;
    }

    source = "abchdcba";
    iter = c1->createCollationElementIterator(source);
    backAndForth(*iter);
    delete iter;
    delete c1;

    // Test with an expanding character sequence
    RuleBasedCollator *c2 = NULL;
    c2 = new RuleBasedCollator("< a < b < c/abd < d", status);

    if (c2 == NULL || U_FAILURE(status))
    {
        errln("Couldn't create a RuleBasedCollator with an expanding sequence.");
        delete c2;
        return;
    }

    source = "abcd";
    iter = c2->createCollationElementIterator(source);
    backAndForth(*iter);
    delete iter;
    delete c2;

    // Now try both
    RuleBasedCollator *c3 = NULL;
    c3 = new RuleBasedCollator("< a < b < c/aba < d < z < ch", status);

    if (c3 == NULL || U_FAILURE(status))
    {
        errln("Couldn't create a RuleBasedCollator with both an expanding and a contracting sequence.");
        delete c3;
        return;
    }

    source = "abcdbchdc";
    iter = c3->createCollationElementIterator(source);
    backAndForth(*iter);
    delete iter;
    delete c3;
}

/**
 * Test for getOffset() and setOffset()
 */
void CollationIteratorTest::TestOffset(char *par)
{
    CollationElementIterator *iter = en_us->createCollationElementIterator(test1);

    // Run all the way through the iterator, then get the offset
    int32_t orderLength = 0;
    int32_t *orders = getOrders(*iter, orderLength);

    int32_t offset = iter->getOffset();

    if (offset != test1.length())
    {
        UnicodeString msg1("offset at end != length: ");
        UnicodeString msg2(" vs ");

        errln(msg1 + offset + msg2 + test1.length());
    }

    // Now set the offset back to the beginning and see if it works
    CollationElementIterator *pristine = en_us->createCollationElementIterator(test1);
    UErrorCode status = U_ZERO_ERROR;

    iter->setOffset(0, status);

    if (U_FAILURE(status))
    {
        errln("setOffset failed.");
    }
    else
    {
        assertEqual(*iter, *pristine);
    }

    // TODO: try iterating halfway through a messy string.

    delete pristine;
    delete[] orders;
    delete iter;
}

/**
 * Test for setText()
 */
void CollationIteratorTest::TestSetText(char *par)
{
    CollationElementIterator *iter1 = en_us->createCollationElementIterator(test1);
    CollationElementIterator *iter2 = en_us->createCollationElementIterator(test2);
    UErrorCode status = U_ZERO_ERROR;

    // Run through the second iterator just to exercise it
    int32_t c = iter2->next(status);
    int32_t i = 0;

    while ( ++i < 10 && c != CollationElementIterator::NULLORDER)
    {
        if (U_FAILURE(status))
        {
            errln("iter2->next() returned an error.");
            delete iter2;
            delete iter1;
        }

        c = iter2->next(status);
    }

    // Now set it to point to the same string as the first iterator
    iter2->setText(test1, status);

    if (U_FAILURE(status))
    {
        errln("call to inter2->setText(test1) failed.");
    }
    else
    {
        assertEqual(*iter1, *iter2);
    }

    delete iter2;
    delete iter1;
}

/** @bug 4108762
 * Test for getMaxExpansion()
 */
void CollationIteratorTest::TestMaxExpansion(char *par)
{
    // Try a simple one first:
    // The only expansion ends with 'e' and has length 2
    UnicodeString rule1("< a & ae = ");
    rule1 += (UChar)0x00e4;
    rule1 += " < b < e";
    ExpansionRecord test1[] =
    {
        {0x61, 1},
        {0x62, 1},
        {0x65, 2}
    };
    verifyExpansion(rule1, test1, ARRAY_LENGTH(test1));
    
    // Now a more complicated one:
    //   "a1" --> "ae"
    //   "z" --> "aeef"
    //
    UnicodeString rule2("< a & ae = a1 & aeef = z < b < e < f");
    ExpansionRecord test2[] =
    {
        {0x61, 1},
        {0x62, 1},
        {0x65, 2},
        {0x66, 4}
    };
    verifyExpansion(rule2, test2, ARRAY_LENGTH(test2));
}

/*
 * @bug 4157299
 */
void CollationIteratorTest::TestClearBuffers(char *par)
{
    UErrorCode status = U_ZERO_ERROR;
    RuleBasedCollator *c = NULL;
    c = new RuleBasedCollator("< a < b < c & ab = d", status);

    if (c == NULL || U_FAILURE(status))
    {
        errln("Couldn't create a RuleBasedCollator.");
        delete c;
        return;
    }

    UnicodeString source("abcd");
    CollationElementIterator *i = c->createCollationElementIterator(source);
    int32_t e0 = i->next(status);    // save the first collation element

    if (U_FAILURE(status))
    {
        errln("call to i->next() failed");
        goto bail;
    }

    i->setOffset(3, status);        // go to the expanding character

    if (U_FAILURE(status))
    {
        errln("call to i->setOffset(3) failed");
        goto bail;
    }

    i->next(status);                // but only use up half of it

    if (U_FAILURE(status))
    {
        errln("call to i->next() failed");
        goto bail;
    }

    i->setOffset(0, status);        // go back to the beginning

    if (U_FAILURE(status))
    {
        errln("call to i->setOffset(0) failed");
        goto bail;
    }

    {
        // This is in it's own block to stop a stupid compiler
        // error about the goto's skipping the initialization
        // of e...
        int32_t e = i->next(status);    // and get this one again

        if (U_FAILURE(status))
        {
            errln("call to i->next() failed.");
            goto bail;
        }

        if (e != e0)
        {
            UnicodeString msg;
            
            msg += "got 0x";
            appendHex(e, 8, msg);
            msg += ", expected 0x";
            appendHex(e0, 8, msg);

            errln(msg);
        }
    }

bail:
    delete i;
    delete c;
}

void CollationIteratorTest::backAndForth(CollationElementIterator &iter)
{
    // Run through the iterator forwards and stick it into an array
    int32_t orderLength = 0;
    int32_t *orders = getOrders(iter, orderLength);
    UErrorCode status = U_ZERO_ERROR;

    // Now go through it backwards and make sure we get the same values
    int32_t index = orderLength;
    int32_t o;

    while ((o = iter.previous(status)) != CollationElementIterator::NULLORDER)
    {
        if (o != orders[--index])
        {
            UnicodeString msg1("Mismatch at index ");
            UnicodeString msg2(": 0x");
            appendHex(orders[index], 8, msg2);
            msg2 += " vs 0x";
            appendHex(o, 8, msg2);

            errln(msg1 + index + msg2);
            break;
        }
    }

    if (index != 0)
    {
        UnicodeString msg("Didn't get back to beginning - index is ");
        errln(msg + index);

        iter.reset();
        err("next: ");
        while ((o = iter.next(status)) != CollationElementIterator::NULLORDER)
        {
            UnicodeString hexString("0x");

            appendHex(0, 8, hexString);
            hexString += " ";
            err(hexString);
        }
        errln("");

        err("prev: ");
        while ((o = iter.previous(status)) != CollationElementIterator::NULLORDER)
        {
            UnicodeString hexString("0x");

            appendHex(o, 8, hexString);
            hexString += " ";
             err(hexString);
        }
        errln("");
    }

    delete[] orders;
}

/**
 * Verify that getMaxExpansion works on a given set of collation rules
 *
 * The first row of the "tests" array contains the collation rules
 * at index 0, and the string at index 1 is ignored.
 *
 * Subsequent rows of the array contain a character and a number, both
 * represented as strings.  The character's collation order is determined,
 * and getMaxExpansion is called for that character.  If its value is
 * not equal to the specified number, an error results.
 */
void CollationIteratorTest::verifyExpansion(UnicodeString rules, ExpansionRecord tests[], int32_t testCount)
{
    UErrorCode status = U_ZERO_ERROR;
    RuleBasedCollator *coll = NULL;
    coll = new RuleBasedCollator(rules, status);

    if (coll == NULL || U_FAILURE(status))
    {
        errln("Couldn't create a RuleBasedCollator.");
        delete coll;
        return;
    }

    UnicodeString source("");
    CollationElementIterator *iter = coll->createCollationElementIterator(source);

    int32_t i;
    for (i = 1; i < testCount; i += 1)
    {
        // First get the collation key that the test string expands to
        UnicodeString test(&tests[i].character, 1);
        iter->setText(test, status);

        if (U_FAILURE(status))
        {
            errln("call to iter->setText() failed.");
            return;
        }
        
        int32_t order = iter->next(status);

        if (U_FAILURE(status))
        {
            errln("call to iter->next() failed.");
            return;
        }
        
        if (order == CollationElementIterator::NULLORDER || iter->next(status) != CollationElementIterator::NULLORDER)
        {
            UnicodeString msg("verifyExpansion: '");
            
            msg += test;
            msg += "' has multiple orders:";
            orderString(*iter, msg);

            iter->reset();
            errln(msg);
        }
        
        int32_t expansion = iter->getMaxExpansion(order);
        int32_t expect = tests[i].count;
        
        if (expansion != expect)
        {
            UnicodeString msg1("expansion for '");
            
            msg1 += test;
            msg1 += "' is wrong: expected ";

            UnicodeString msg2(", got ");

            errln(msg1 + expect + msg2 + expansion);
        }
    }
}

/**
 * Return an integer array containing all of the collation orders
 * returned by calls to next on the specified iterator
 */
int32_t *CollationIteratorTest::getOrders(CollationElementIterator &iter, int32_t &orderLength)
{
    int32_t maxSize = 100;
    int32_t size = 0;
    int32_t *orders = new int32_t[maxSize];
    UErrorCode status = U_ZERO_ERROR;

    int32_t order;
    while ((order = iter.next(status)) != CollationElementIterator::NULLORDER)
    {
        if (size == maxSize)
        {
            maxSize *= 2;
            int32_t *temp = new int32_t[maxSize];

            memcpy(temp, orders, size * sizeof(int32_t));
            delete[] orders;
            orders = temp;
        }

        orders[size++] = order;
    }

    if (maxSize > size)
    {
        int32_t *temp = new int32_t[size];

        memcpy(temp, orders, size * sizeof(int32_t));
        delete[] orders;
        orders = temp;
    }

    orderLength = size;
    return orders;
}

/**
 * Return a string containing all of the collation orders
 * returned by calls to next on the specified iterator
 */
UnicodeString &CollationIteratorTest::orderString(CollationElementIterator &iter, UnicodeString &target)
{
    int32_t order;
    UErrorCode status = U_ZERO_ERROR;

    while ((order = iter.next(status)) != CollationElementIterator::NULLORDER)
    {
        target += "0x";
        appendHex(order, 8, target);
        target += " ";
    }

    return target;
}

void CollationIteratorTest::assertEqual(CollationElementIterator &i1, CollationElementIterator &i2)
{
    int32_t c1, c2, count = 0;
    UErrorCode status = U_ZERO_ERROR;

    do
    {
        c1 = i1.next(status);
        c2 = i2.next(status);

        if (c1 != c2)
        {
            UnicodeString msg, msg1("    ");
            
            msg += msg1 + count;
            msg += ": strength(0x";
            appendHex(c1, 8, msg);
            msg += ") != strength(0x";
            appendHex(c2, 8, msg);
            msg += ")";

            errln(msg);
            break;
        }

        count += 1;
    }
    while (c1 != CollationElementIterator::NULLORDER);
}

void CollationIteratorTest::runIndexedTest(int32_t index, bool_t exec, char* &name, char* par)
{
    if (exec)
    {
        logln("Collation Iteration Tests: ");
    }

    switch (index)
    {
        case  0: name = "TestPrevious";        if (exec) TestPrevious(par);     break;
        case  1: name = "TestOffset";        if (exec) TestOffset(par);         break;
        case  2: name = "TestSetText";        if (exec) TestSetText(par);         break;
        case  3: name = "TestMaxExpansion";    if (exec) TestMaxExpansion(par); break;
        case  4: name = "TestClearBuffers"; if (exec) TestClearBuffers(par); break;
        default: name = ""; break;
    }
}

