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

#include "simplethread.h"

#include "unicode/utypes.h"
#include "unicode/ustring.h"
#include "umutex.h"
#include "cmemory.h"
#include "cstring.h"
#include "uparse.h"
#include "unicode/localpointer.h"
#include "unicode/resbund.h"
#include "unicode/udata.h"
#include "unicode/uloc.h"
#include "unicode/locid.h"
#include "putilimp.h"
#include "intltest.h"
#include "tsmthred.h"
#include "unicode/ushape.h"
#include "unicode/translit.h"
#include "sharedobject.h"
#include "unifiedcache.h"
#include "uassert.h"


#define TSMTHREAD_FAIL(msg) errln("%s at file %s, line %d", msg, __FILE__, __LINE__)
#define TSMTHREAD_ASSERT(expr) {if (!(expr)) {TSMTHREAD_FAIL("Fail");}}
#define TSMTHREAD_ASSERT_SUCCESS(status) {if (U_FAILURE(status)) { \
                  errln("file: %s:%d status = %s\n", __FILE__, __LINE__, u_errorName(status));}}

MultithreadTest::MultithreadTest()
{
}

MultithreadTest::~MultithreadTest()
{
}

#include <stdio.h>
#include <string.h>
#include <ctype.h>    // tolower, toupper

#include "unicode/putil.h"

// for mthreadtest
#include "unicode/numfmt.h"
#include "unicode/choicfmt.h"
#include "unicode/msgfmt.h"
#include "unicode/locid.h"
#include "unicode/coll.h"
#include "unicode/calendar.h"
#include "ucaconf.h"


void MultithreadTest::runIndexedTest( int32_t index, UBool exec,
                const char* &name, char* /*par*/ ) {
    if (exec)
        logln("TestSuite MultithreadTest: ");
    switch (index) {
    case 0:
        name = "TestThreads";
        if (exec)
            TestThreads();
        break;

    case 1:
        name = "TestMutex";
        if (exec)
            TestMutex();
        break;

    case 2:
        name = "TestThreadedIntl";
#if !UCONFIG_NO_FORMATTING
        if (exec) {
            TestThreadedIntl();
        }
#endif
        break;

    case 3:
      name = "TestCollators";
#if !UCONFIG_NO_COLLATION
      if (exec) {
            TestCollators();
      }
#endif /* #if !UCONFIG_NO_COLLATION */
      break;

    case 4:
        name = "TestString";
        if (exec) {
            TestString();
        }
        break;

    case 5:
        name = "TestArabicShapingThreads";
        if (exec) {
            TestArabicShapingThreads();
        }
        break;

    case 6:
        name = "TestAnyTranslit";
        if (exec) {
            TestAnyTranslit();
        }
        break;

    case 7:
        name = "TestConditionVariables";
        if (exec) {
            TestConditionVariables();
        }
        break;
    case 8:
        name = "TestUnifiedCache";
        if (exec) {
            TestUnifiedCache();
        }
        break;
    case 9:
        name = "TestBreakTranslit";
        if (exec) {
            TestBreakTranslit();
        }
        break;
    default:
        name = "";
        break; //needed to end loop
    }
}


//-----------------------------------------------------------------------------------
//
//   TestThreads -- see if threads really work at all.
//
//   Set up N threads pointing at N chars. When they are started, they will
//   set their chars. At the end we make sure they are all set.
//
//-----------------------------------------------------------------------------------

class TestThreadsThread : public SimpleThread
{
public:
    TestThreadsThread(char* whatToChange) { fWhatToChange = whatToChange; }
    virtual void run() { Mutex m;
                         *fWhatToChange = '*';
    }
private:
    char *fWhatToChange;
};


void MultithreadTest::TestThreads()
{
    static const int32_t THREADTEST_NRTHREADS = 8;
    char threadTestChars[THREADTEST_NRTHREADS + 1];
    SimpleThread *threads[THREADTEST_NRTHREADS];
    int32_t numThreadsStarted = 0;

    int32_t i;
    for(i=0;i<THREADTEST_NRTHREADS;i++)
    {
        threadTestChars[i] = ' ';
        threads[i] = new TestThreadsThread(&threadTestChars[i]);
    }
    threadTestChars[THREADTEST_NRTHREADS] = '\0';

    logln("->" + UnicodeString(threadTestChars) + "<- Firing off threads.. ");
    for(i=0;i<THREADTEST_NRTHREADS;i++)
    {
        if (threads[i]->start() != 0) {
            errln("Error starting thread %d", i);
        }
        else {
            numThreadsStarted++;
        }
        logln(" Subthread started.");
    }

    if (numThreadsStarted != THREADTEST_NRTHREADS) {
        errln("Not all threads could be started for testing!");
        return;
    }

    logln("Waiting for threads to be set..");
    for(i=0; i<THREADTEST_NRTHREADS; i++) {
        threads[i]->join();
        if (threadTestChars[i] != '*') {
            errln("%s:%d Thread %d failed.", __FILE__, __LINE__, i);
        }
        delete threads[i];
    }
}


//-----------------------------------------------------------------------------------
//
//   TestArabicShapeThreads -- see if calls to u_shapeArabic in many threads works successfully
//
//   Set up N threads pointing at N chars. When they are started, they will make calls to doTailTest which tests
//   u_shapeArabic, if the calls are successful it will the set * chars.
//   At the end we make sure all threads managed to run u_shapeArabic successfully.
//   This is a unit test for ticket 9473
//
//-----------------------------------------------------------------------------------

class TestArabicShapeThreads : public SimpleThread
{
public:
    TestArabicShapeThreads() {};
    virtual void run() { doTailTest(); };
private:
	void doTailTest();
};


void TestArabicShapeThreads::doTailTest(void) {
    static const UChar src[] = { 0x0020, 0x0633, 0 };
    static const UChar dst_old[] = { 0xFEB1, 0x200B,0 };
    static const UChar dst_new[] = { 0xFEB1, 0xFE73,0 };
    UChar dst[3] = { 0x0000, 0x0000,0 };
    int32_t length;
    UErrorCode status;

    for (int32_t loopCount = 0; loopCount < 100; loopCount++) {
        status = U_ZERO_ERROR;
        length = u_shapeArabic(src, -1, dst, UPRV_LENGTHOF(dst),
                U_SHAPE_LETTERS_SHAPE|U_SHAPE_SEEN_TWOCELL_NEAR, &status);
        if(U_FAILURE(status)) {
            IntlTest::gTest->errln("Fail: status %s\n", u_errorName(status));
            return;
        } else if(length!=2) {
            IntlTest::gTest->errln("Fail: len %d expected 3\n", length);
            return;
        } else if(u_strncmp(dst,dst_old,UPRV_LENGTHOF(dst))) {
            IntlTest::gTest->errln("Fail: got U+%04X U+%04X expected U+%04X U+%04X\n",
                    dst[0],dst[1],dst_old[0],dst_old[1]);
            return;
        }


        //"Trying new tail
        status = U_ZERO_ERROR;
        length = u_shapeArabic(src, -1, dst, UPRV_LENGTHOF(dst),
                U_SHAPE_LETTERS_SHAPE|U_SHAPE_SEEN_TWOCELL_NEAR|U_SHAPE_TAIL_NEW_UNICODE, &status);
        if(U_FAILURE(status)) {
            IntlTest::gTest->errln("Fail: status %s\n", u_errorName(status));
            return;
        } else if(length!=2) {
            IntlTest::gTest->errln("Fail: len %d expected 3\n", length);
            return;
        } else if(u_strncmp(dst,dst_new,UPRV_LENGTHOF(dst))) {
            IntlTest::gTest->errln("Fail: got U+%04X U+%04X expected U+%04X U+%04X\n",
                    dst[0],dst[1],dst_new[0],dst_new[1]);
            return;
        }
    }
    return;
}
	

void MultithreadTest::TestArabicShapingThreads()
{
    TestArabicShapeThreads threads[30];

    int32_t i;

    logln("-> do TestArabicShapingThreads <- Firing off threads.. ");
    for(i=0; i < UPRV_LENGTHOF(threads); i++) {
        if (threads[i].start() != 0) {
            errln("Error starting thread %d", i);
        }
    }

    for(i=0; i < UPRV_LENGTHOF(threads); i++) {
        threads[i].join();
    }
    logln("->TestArabicShapingThreads <- Got all threads! cya");
}


//-----------------------------------------------------------------------
//
//  TestMutex  - a simple (non-stress) test to verify that ICU mutexes
//               and condition variables are functioning.  Does not test the use of
//               mutexes within ICU services, but rather that the
//               platform's mutex support is at least superficially there.
//
//----------------------------------------------------------------------
static UMutex         gTestMutexA          = U_MUTEX_INITIALIZER;
static UConditionVar  gThreadsCountChanged = U_CONDITION_INITIALIZER;

static int     gThreadsStarted = 0;
static int     gThreadsInMiddle = 0;
static int     gThreadsDone = 0;

static const int TESTMUTEX_THREAD_COUNT = 40;

class TestMutexThread : public SimpleThread
{
public:
    virtual void run() {
        // This is the code that each of the spawned threads runs.
        // All threads move together throught the started - middle - done sequence together,
        // waiting for all other threads to reach each point before advancing.
        umtx_lock(&gTestMutexA);
        gThreadsStarted += 1;
        umtx_condBroadcast(&gThreadsCountChanged);
        while (gThreadsStarted < TESTMUTEX_THREAD_COUNT) {
            if (gThreadsInMiddle != 0) {
                IntlTest::gTest->errln(
                    "%s:%d gThreadsInMiddle = %d. Expected 0.", __FILE__, __LINE__, gThreadsInMiddle);
                return;
            }
            umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
        }

        gThreadsInMiddle += 1;
        umtx_condBroadcast(&gThreadsCountChanged);
        while (gThreadsInMiddle < TESTMUTEX_THREAD_COUNT) {
            if (gThreadsDone != 0) {
                IntlTest::gTest->errln(
                    "%s:%d gThreadsDone = %d. Expected 0.", __FILE__, __LINE__, gThreadsDone);
                return;
            }
            umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
        }

        gThreadsDone += 1;
        umtx_condBroadcast(&gThreadsCountChanged);
        while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
            umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
        }
        umtx_unlock(&gTestMutexA);
    }
};

void MultithreadTest::TestMutex()
{
    gThreadsStarted = 0;
    gThreadsInMiddle = 0;
    gThreadsDone = 0;
    int32_t i = 0;
    TestMutexThread  threads[TESTMUTEX_THREAD_COUNT];
    umtx_lock(&gTestMutexA);
    for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
        if (threads[i].start() != 0) {
            errln("%s:%d Error starting thread %d", __FILE__, __LINE__, i);
            return;
        }
    }

    // Because we are holding gTestMutexA, all of the threads should be blocked
    // at the start of their run() function.
    if (gThreadsStarted != 0) {
        errln("%s:%d gThreadsStarted=%d. Expected 0.", __FILE__, __LINE__, gThreadsStarted);
        return;
    }

    while (gThreadsInMiddle < TESTMUTEX_THREAD_COUNT) {
        if (gThreadsDone != 0) {
            errln("%s:%d gThreadsDone=%d. Expected 0.", __FILE__, __LINE__, gThreadsStarted);
            return;
        }
        umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
    }

    while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
        umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
    }
    umtx_unlock(&gTestMutexA);

    for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
        threads[i].join();
    }
}


//-------------------------------------------------------------------------------------------
//
//   TestMultithreadedIntl.  Test ICU Formatting in a multi-threaded environment
//
//-------------------------------------------------------------------------------------------


// * Show exactly where the string's differences lie.
UnicodeString showDifference(const UnicodeString& expected, const UnicodeString& result)
{
    UnicodeString res;
    res = expected + "<Expected\n";
    if(expected.length() != result.length())
        res += " [ Different lengths ] \n";
    else
    {
        for(int32_t i=0;i<expected.length();i++)
        {
            if(expected[i] == result[i])
            {
                res += " ";
            }
            else
            {
                res += "|";
            }
        }
        res += "<Differences";
        res += "\n";
    }
    res += result + "<Result\n";

    return res;
}


//-------------------------------------------------------------------------------------------
//
//   FormatThreadTest - a thread that tests performing a number of numberformats.
//
//-------------------------------------------------------------------------------------------

const int kFormatThreadIterations = 100;  // # of iterations per thread
const int kFormatThreadThreads    = 10;  // # of threads to spawn

#if !UCONFIG_NO_FORMATTING



struct FormatThreadTestData
{
    double number;
    UnicodeString string;
    FormatThreadTestData(double a, const UnicodeString& b) : number(a),string(b) {}
} ;


// "Someone from {2} is receiving a #{0} error - {1}. Their telephone call is costing {3 number,currency}."

static void formatErrorMessage(UErrorCode &realStatus, const UnicodeString& pattern, const Locale& theLocale,
                     UErrorCode inStatus0, /* statusString 1 */ const Locale &inCountry2, double currency3, // these numbers are the message arguments.
                     UnicodeString &result)
{
    if(U_FAILURE(realStatus))
        return; // you messed up

    UnicodeString errString1(u_errorName(inStatus0));

    UnicodeString countryName2;
    inCountry2.getDisplayCountry(theLocale,countryName2);

    Formattable myArgs[] = {
        Formattable((int32_t)inStatus0),   // inStatus0      {0}
        Formattable(errString1), // statusString1 {1}
        Formattable(countryName2),  // inCountry2 {2}
        Formattable(currency3)// currency3  {3,number,currency}
    };

    MessageFormat *fmt = new MessageFormat("MessageFormat's API is broken!!!!!!!!!!!",realStatus);
    fmt->setLocale(theLocale);
    fmt->applyPattern(pattern, realStatus);

    if (U_FAILURE(realStatus)) {
        delete fmt;
        return;
    }

    FieldPosition ignore = 0;
    fmt->format(myArgs,4,result,ignore,realStatus);

    delete fmt;
}

/**
  * Shared formatters &  data used by instances of ThreadSafeFormat.
  * Exactly one instance of this class is created, and it is then shared concurrently
  * by the multiple instances of ThreadSafeFormat.
  */
class ThreadSafeFormatSharedData {
  public:
    ThreadSafeFormatSharedData(UErrorCode &status);
    ~ThreadSafeFormatSharedData();
    LocalPointer<NumberFormat>  fFormat;
    Formattable    fYDDThing;
    Formattable    fBBDThing;
    UnicodeString  fYDDStr;
    UnicodeString  fBBDStr;
};

const ThreadSafeFormatSharedData *gSharedData = NULL;

ThreadSafeFormatSharedData::ThreadSafeFormatSharedData(UErrorCode &status) {
    fFormat.adoptInstead(NumberFormat::createCurrencyInstance(Locale::getUS(), status));
    static const UChar kYDD[] = { 0x59, 0x44, 0x44, 0x00 };
    static const UChar kBBD[] = { 0x42, 0x42, 0x44, 0x00 };
    fYDDThing.adoptObject(new CurrencyAmount(123.456, kYDD, status));
    fBBDThing.adoptObject(new CurrencyAmount(987.654, kBBD, status));
    if (U_FAILURE(status)) {
        return;
    }
    fFormat->format(fYDDThing, fYDDStr, NULL, status);
    fFormat->format(fBBDThing, fBBDStr, NULL, status);
    gSharedData = this;
}

ThreadSafeFormatSharedData::~ThreadSafeFormatSharedData() {
    gSharedData = NULL;
}

/**
 * Class for thread-safe testing of format.
 *   Instances of this class appear as members of class FormatThreadTest.
 *   Multiple instances of FormatThreadTest coexist.
 *   ThreadSafeFormat::doStuff() is called concurrently to test the thread safety of
 *   various shared format operations.
 */
class ThreadSafeFormat {
public:
  /* give a unique offset to each thread */
  ThreadSafeFormat(UErrorCode &status);
  UBool doStuff(int32_t offset, UnicodeString &appendErr, UErrorCode &status) const;
private:
  LocalPointer<NumberFormat> fFormat; // formatter - en_US constructed currency
};


ThreadSafeFormat::ThreadSafeFormat(UErrorCode &status) {
  fFormat.adoptInstead(NumberFormat::createCurrencyInstance(Locale::getUS(), status));
}

static const UChar kUSD[] = { 0x55, 0x53, 0x44, 0x00 };

UBool ThreadSafeFormat::doStuff(int32_t offset, UnicodeString &appendErr, UErrorCode &status) const {
  UBool okay = TRUE;

  if(u_strcmp(fFormat->getCurrency(), kUSD)) {
    appendErr.append("fFormat currency != ")
      .append(kUSD)
      .append(", =")
      .append(fFormat->getCurrency())
      .append("! ");
    okay = FALSE;
  }

  if(u_strcmp(gSharedData->fFormat->getCurrency(), kUSD)) {
    appendErr.append("gFormat currency != ")
      .append(kUSD)
      .append(", =")
      .append(gSharedData->fFormat->getCurrency())
      .append("! ");
    okay = FALSE;
  }
  UnicodeString str;
  const UnicodeString *o=NULL;
  Formattable f;
  const NumberFormat *nf = NULL; // only operate on it as const.
  switch(offset%4) {
  case 0:  f = gSharedData->fYDDThing;  o = &gSharedData->fYDDStr;  nf = gSharedData->fFormat.getAlias();  break;
  case 1:  f = gSharedData->fBBDThing;  o = &gSharedData->fBBDStr;  nf = gSharedData->fFormat.getAlias();  break;
  case 2:  f = gSharedData->fYDDThing;  o = &gSharedData->fYDDStr;  nf = fFormat.getAlias();  break;
  case 3:  f = gSharedData->fBBDThing;  o = &gSharedData->fBBDStr;  nf = fFormat.getAlias();  break;
  }
  nf->format(f, str, NULL, status);

  if(*o != str) {
    appendErr.append(showDifference(*o, str));
    okay = FALSE;
  }
  return okay;
}

UBool U_CALLCONV isAcceptable(void *, const char *, const char *, const UDataInfo *) {
    return TRUE;
}

//static UMTX debugMutex = NULL;
//static UMTX gDebugMutex;


class FormatThreadTest : public SimpleThread
{
public:
    int     fNum;
    int     fTraceInfo;

    LocalPointer<ThreadSafeFormat> fTSF;

    FormatThreadTest() // constructor is NOT multithread safe.
        : SimpleThread(),
        fNum(0),
        fTraceInfo(0),
        fTSF(NULL),
        fOffset(0)
        // the locale to use
    {
        UErrorCode status = U_ZERO_ERROR;      // TODO: rearrange code to allow checking of status.
        fTSF.adoptInstead(new ThreadSafeFormat(status));
        static int32_t fgOffset = 0;
        fgOffset += 3;
        fOffset = fgOffset;
    }


    virtual void run()
    {
        fTraceInfo                     = 1;
        LocalPointer<NumberFormat> percentFormatter;
        UErrorCode status = U_ZERO_ERROR;

#if 0
        // debugging code,
        for (int i=0; i<4000; i++) {
            status = U_ZERO_ERROR;
            UDataMemory *data1 = udata_openChoice(0, "res", "en_US", isAcceptable, 0, &status);
            UDataMemory *data2 = udata_openChoice(0, "res", "fr", isAcceptable, 0, &status);
            udata_close(data1);
            udata_close(data2);
            if (U_FAILURE(status)) {
                error("udata_openChoice failed.\n");
                break;
            }
        }
        return;
#endif

#if 0
        // debugging code,
        int m;
        for (m=0; m<4000; m++) {
            status         = U_ZERO_ERROR;
            UResourceBundle *res   = NULL;
            const char *localeName = NULL;

            Locale  loc = Locale::getEnglish();

            localeName = loc.getName();
            // localeName = "en";

            // ResourceBundle bund = ResourceBundle(0, loc, status);
            //umtx_lock(&gDebugMutex);
            res = ures_open(NULL, localeName, &status);
            //umtx_unlock(&gDebugMutex);

            //umtx_lock(&gDebugMutex);
            ures_close(res);
            //umtx_unlock(&gDebugMutex);

            if (U_FAILURE(status)) {
                error("Resource bundle construction failed.\n");
                break;
            }
        }
        return;
#endif

        // Keep this data here to avoid static initialization.
        FormatThreadTestData kNumberFormatTestData[] =
        {
            FormatThreadTestData((double)5.0, UnicodeString("5", "")),
                FormatThreadTestData( 6.0, UnicodeString("6", "")),
                FormatThreadTestData( 20.0, UnicodeString("20", "")),
                FormatThreadTestData( 8.0, UnicodeString("8", "")),
                FormatThreadTestData( 8.3, UnicodeString("8.3", "")),
                FormatThreadTestData( 12345, UnicodeString("12,345", "")),
                FormatThreadTestData( 81890.23, UnicodeString("81,890.23", "")),
        };
        int32_t kNumberFormatTestDataLength = UPRV_LENGTHOF(kNumberFormatTestData);

        // Keep this data here to avoid static initialization.
        FormatThreadTestData kPercentFormatTestData[] =
        {
            FormatThreadTestData((double)5.0, CharsToUnicodeString("500\\u00a0%")),
                FormatThreadTestData( 1.0, CharsToUnicodeString("100\\u00a0%")),
                FormatThreadTestData( 0.26, CharsToUnicodeString("26\\u00a0%")),
                FormatThreadTestData(
                   16384.99, CharsToUnicodeString("1\\u00a0638\\u00a0499\\u00a0%")), // U+00a0 = NBSP
                FormatThreadTestData(
                    81890.23, CharsToUnicodeString("8\\u00a0189\\u00a0023\\u00a0%")),
        };
        int32_t kPercentFormatTestDataLength = UPRV_LENGTHOF(kPercentFormatTestData);
        int32_t iteration;

        status = U_ZERO_ERROR;
        LocalPointer<NumberFormat> formatter(NumberFormat::createInstance(Locale::getEnglish(),status));
        if(U_FAILURE(status)) {
            IntlTest::gTest->errln("%s:%d Error %s on NumberFormat::createInstance().",
                    __FILE__, __LINE__, u_errorName(status));
            goto cleanupAndReturn;
        }

        percentFormatter.adoptInstead(NumberFormat::createPercentInstance(Locale::getFrench(),status));
        if(U_FAILURE(status))             {
            IntlTest::gTest->errln("%s:%d Error %s on NumberFormat::createPercentInstance().",
                    __FILE__, __LINE__, u_errorName(status));
            goto cleanupAndReturn;
        }

        for(iteration = 0;!IntlTest::gTest->getErrors() && iteration<kFormatThreadIterations;iteration++)
        {

            int32_t whichLine = (iteration + fOffset)%kNumberFormatTestDataLength;

            UnicodeString  output;

            formatter->format(kNumberFormatTestData[whichLine].number, output);

            if(0 != output.compare(kNumberFormatTestData[whichLine].string)) {
                IntlTest::gTest->errln("format().. expected " + kNumberFormatTestData[whichLine].string
                        + " got " + output);
                goto cleanupAndReturn;
            }

            // Now check percent.
            output.remove();
            whichLine = (iteration + fOffset)%kPercentFormatTestDataLength;

            percentFormatter->format(kPercentFormatTestData[whichLine].number, output);
            if(0 != output.compare(kPercentFormatTestData[whichLine].string))
            {
                IntlTest::gTest->errln("percent format().. \n" +
                        showDifference(kPercentFormatTestData[whichLine].string,output));
                goto cleanupAndReturn;
            }

            // Test message error
            const int       kNumberOfMessageTests = 3;
            UErrorCode      statusToCheck;
            UnicodeString   patternToCheck;
            Locale          messageLocale;
            Locale          countryToCheck;
            double          currencyToCheck;

            UnicodeString   expected;

            // load the cases.
            switch((iteration+fOffset) % kNumberOfMessageTests)
            {
            default:
            case 0:
                statusToCheck=                      U_FILE_ACCESS_ERROR;
                patternToCheck=        "0:Someone from {2} is receiving a #{0}"
                                       " error - {1}. Their telephone call is costing "
                                       "{3,number,currency}."; // number,currency
                messageLocale=                      Locale("en","US");
                countryToCheck=                     Locale("","HR");
                currencyToCheck=                    8192.77;
                expected=  "0:Someone from Croatia is receiving a #4 error - "
                            "U_FILE_ACCESS_ERROR. Their telephone call is costing $8,192.77.";
                break;
            case 1:
                statusToCheck=                      U_INDEX_OUTOFBOUNDS_ERROR;
                patternToCheck=                     "1:A customer in {2} is receiving a #{0} error - {1}. "
                                                    "Their telephone call is costing {3,number,currency}."; // number,currency
                messageLocale=                      Locale("de","DE@currency=DEM");
                countryToCheck=                     Locale("","BF");
                currencyToCheck=                    2.32;
                expected=                           CharsToUnicodeString(
                                                    "1:A customer in Burkina Faso is receiving a #8 error - U_INDEX_OUTOFBOUNDS_ERROR. "
                                                    "Their telephone call is costing 2,32\\u00A0DM.");
                break;
            case 2:
                statusToCheck=                      U_MEMORY_ALLOCATION_ERROR;
                patternToCheck=   "2:user in {2} is receiving a #{0} error - {1}. "
                                  "They insist they just spent {3,number,currency} "
                                  "on memory."; // number,currency
                messageLocale=                      Locale("de","AT@currency=ATS"); // Austrian German
                countryToCheck=                     Locale("","US"); // hmm
                currencyToCheck=                    40193.12;
                expected=       CharsToUnicodeString(
                            "2:user in Vereinigte Staaten is receiving a #7 error"
                            " - U_MEMORY_ALLOCATION_ERROR. They insist they just spent"
                            " \\u00f6S\\u00A040.193,12 on memory.");
                break;
            }

            UnicodeString result;
            UErrorCode status = U_ZERO_ERROR;
            formatErrorMessage(status,patternToCheck,messageLocale,statusToCheck,
                                countryToCheck,currencyToCheck,result);
            if(U_FAILURE(status))
            {
                UnicodeString tmp(u_errorName(status));
                IntlTest::gTest->errln("Failure on message format, pattern=" + patternToCheck +
                        ", error = " + tmp);
                goto cleanupAndReturn;
            }

            if(result != expected)
            {
                IntlTest::gTest->errln("PatternFormat: \n" + showDifference(expected,result));
                goto cleanupAndReturn;
            }
            // test the Thread Safe Format
            UnicodeString appendErr;
            if(!fTSF->doStuff(fNum, appendErr, status)) {
              IntlTest::gTest->errln(appendErr);
              goto cleanupAndReturn;
            }
        }   /*  end of for loop */



cleanupAndReturn:
        fTraceInfo = 2;
    }

private:
    int32_t fOffset; // where we are testing from.
};

// ** The actual test function.

void MultithreadTest::TestThreadedIntl()
{
    UnicodeString theErr;

    UErrorCode threadSafeErr = U_ZERO_ERROR;

    ThreadSafeFormatSharedData sharedData(threadSafeErr);
    assertSuccess("initializing ThreadSafeFormat", threadSafeErr, TRUE);

    //
    //  Create and start the test threads
    //
    logln("Spawning: %d threads * %d iterations each.",
                kFormatThreadThreads, kFormatThreadIterations);
    FormatThreadTest tests[kFormatThreadThreads];
    int32_t j;
    for(j = 0; j < UPRV_LENGTHOF(tests); j++) {
        tests[j].fNum = j;
        int32_t threadStatus = tests[j].start();
        if (threadStatus != 0) {
            errln("%s:%d System Error %d starting thread number %d.",
                    __FILE__, __LINE__, threadStatus, j);
            return;
        }
    }


    for (j=0; j<UPRV_LENGTHOF(tests); j++) {
        tests[j].join();
        logln("Thread # %d is complete..", j);
    }
}
#endif /* #if !UCONFIG_NO_FORMATTING */





//-------------------------------------------------------------------------------------------
//
// Collation threading test
//
//-------------------------------------------------------------------------------------------
#if !UCONFIG_NO_COLLATION

#define kCollatorThreadThreads   10  // # of threads to spawn
#define kCollatorThreadPatience kCollatorThreadThreads*30

struct Line {
    UChar buff[25];
    int32_t buflen;
} ;

static UBool
skipLineBecauseOfBug(const UChar *s, int32_t length) {
    // TODO: Fix ICU ticket #8052
    if(length >= 3 &&
            (s[0] == 0xfb2 || s[0] == 0xfb3) &&
            s[1] == 0x334 &&
            (s[2] == 0xf73 || s[2] == 0xf75 || s[2] == 0xf81)) {
        return TRUE;
    }
    return FALSE;
}

static UCollationResult
normalizeResult(int32_t result) {
    return result<0 ? UCOL_LESS : result==0 ? UCOL_EQUAL : UCOL_GREATER;
}

class CollatorThreadTest : public SimpleThread
{
private:
    const Collator *coll;
    const Line *lines;
    int32_t noLines;
    UBool isAtLeastUCA62;
public:
    CollatorThreadTest()  : SimpleThread(),
        coll(NULL),
        lines(NULL),
        noLines(0),
        isAtLeastUCA62(TRUE)
    {
    };
    void setCollator(Collator *c, Line *l, int32_t nl, UBool atLeastUCA62)
    {
        coll = c;
        lines = l;
        noLines = nl;
        isAtLeastUCA62 = atLeastUCA62;
    }
    virtual void run() {
        uint8_t sk1[1024], sk2[1024];
        uint8_t *oldSk = NULL, *newSk = sk1;
        int32_t oldLen = 0;
        int32_t prev = 0;
        int32_t i = 0;

        for(i = 0; i < noLines; i++) {
            if(lines[i].buflen == 0) { continue; }

            if(skipLineBecauseOfBug(lines[i].buff, lines[i].buflen)) { continue; }

            int32_t resLen = coll->getSortKey(lines[i].buff, lines[i].buflen, newSk, 1024);

            if(oldSk != NULL) {
                int32_t skres = strcmp((char *)oldSk, (char *)newSk);
                int32_t cmpres = coll->compare(lines[prev].buff, lines[prev].buflen, lines[i].buff, lines[i].buflen);
                int32_t cmpres2 = coll->compare(lines[i].buff, lines[i].buflen, lines[prev].buff, lines[prev].buflen);

                if(cmpres != -cmpres2) {
                    IntlTest::gTest->errln(UnicodeString("Compare result not symmetrical on line ") + (i + 1));
                    break;
                }

                if(cmpres != normalizeResult(skres)) {
                    IntlTest::gTest->errln(UnicodeString("Difference between coll->compare and sortkey compare on line ") + (i + 1));
                    break;
                }

                int32_t res = cmpres;
                if(res == 0 && !isAtLeastUCA62) {
                    // Up to UCA 6.1, the collation test files use a custom tie-breaker,
                    // comparing the raw input strings.
                    res = u_strcmpCodePointOrder(lines[prev].buff, lines[i].buff);
                    // Starting with UCA 6.2, the collation test files use the standard UCA tie-breaker,
                    // comparing the NFD versions of the input strings,
                    // which we do via setting strength=identical.
                }
                if(res > 0) {
                    IntlTest::gTest->errln(UnicodeString("Line is not greater or equal than previous line, for line ") + (i + 1));
                    break;
                }
            }

            oldSk = newSk;
            oldLen = resLen;
            (void)oldLen;   // Suppress set but not used warning.
            prev = i;

            newSk = (newSk == sk1)?sk2:sk1;
        }
    }
};

void MultithreadTest::TestCollators()
{

    UErrorCode status = U_ZERO_ERROR;
    FILE *testFile = NULL;
    char testDataPath[1024];
    strcpy(testDataPath, IntlTest::getSourceTestData(status));
    if (U_FAILURE(status)) {
        errln("ERROR: could not open test data %s", u_errorName(status));
        return;
    }
    strcat(testDataPath, "CollationTest_");

    const char* type = "NON_IGNORABLE";

    const char *ext = ".txt";
    if(testFile) {
        fclose(testFile);
    }
    char buffer[1024];
    strcpy(buffer, testDataPath);
    strcat(buffer, type);
    size_t bufLen = strlen(buffer);

    // we try to open 3 files:
    // path/CollationTest_type.txt
    // path/CollationTest_type_SHORT.txt
    // path/CollationTest_type_STUB.txt
    // we are going to test with the first one that we manage to open.

    strcpy(buffer+bufLen, ext);

    testFile = fopen(buffer, "rb");

    if(testFile == 0) {
        strcpy(buffer+bufLen, "_SHORT");
        strcat(buffer, ext);
        testFile = fopen(buffer, "rb");

        if(testFile == 0) {
            strcpy(buffer+bufLen, "_STUB");
            strcat(buffer, ext);
            testFile = fopen(buffer, "rb");

            if (testFile == 0) {
                *(buffer+bufLen) = 0;
                dataerrln("could not open any of the conformance test files, tried opening base %s", buffer);
                return;
            } else {
                infoln(
                    "INFO: Working with the stub file.\n"
                    "If you need the full conformance test, please\n"
                    "download the appropriate data files from:\n"
                    "http://source.icu-project.org/repos/icu/tools/trunk/unicodetools/com/ibm/text/data/");
            }
        }
    }

    LocalArray<Line> lines(new Line[200000]);
    memset(lines.getAlias(), 0, sizeof(Line)*200000);
    int32_t lineNum = 0;

    UChar bufferU[1024];
    uint32_t first = 0;

    while (fgets(buffer, 1024, testFile) != NULL) {
        if(*buffer == 0 || buffer[0] == '#') {
            // Store empty and comment lines so that errors are reported
            // for the real test file lines.
            lines[lineNum].buflen = 0;
            lines[lineNum].buff[0] = 0;
        } else {
            int32_t buflen = u_parseString(buffer, bufferU, 1024, &first, &status);
            lines[lineNum].buflen = buflen;
            u_memcpy(lines[lineNum].buff, bufferU, buflen);
            lines[lineNum].buff[buflen] = 0;
        }
        lineNum++;
    }
    fclose(testFile);
    if(U_FAILURE(status)) {
      dataerrln("Couldn't read the test file!");
      return;
    }

    UVersionInfo uniVersion;
    static const UVersionInfo v62 = { 6, 2, 0, 0 };
    u_getUnicodeVersion(uniVersion);
    UBool isAtLeastUCA62 = uprv_memcmp(uniVersion, v62, 4) >= 0;

    LocalPointer<Collator> coll(Collator::createInstance(Locale::getRoot(), status));
    if(U_FAILURE(status)) {
        errcheckln(status, "Couldn't open UCA collator");
        return;
    }
    coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
    coll->setAttribute(UCOL_CASE_FIRST, UCOL_OFF, status);
    coll->setAttribute(UCOL_CASE_LEVEL, UCOL_OFF, status);
    coll->setAttribute(UCOL_STRENGTH, isAtLeastUCA62 ? UCOL_IDENTICAL : UCOL_TERTIARY, status);
    coll->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, status);

    int32_t spawnResult = 0;
    LocalArray<CollatorThreadTest> tests(new CollatorThreadTest[kCollatorThreadThreads]);

    logln(UnicodeString("Spawning: ") + kCollatorThreadThreads + " threads * " + kFormatThreadIterations + " iterations each.");
    int32_t j = 0;
    for(j = 0; j < kCollatorThreadThreads; j++) {
        //logln("Setting collator %i", j);
        tests[j].setCollator(coll.getAlias(), lines.getAlias(), lineNum, isAtLeastUCA62);
    }
    for(j = 0; j < kCollatorThreadThreads; j++) {
        log("%i ", j);
        spawnResult = tests[j].start();
        if(spawnResult != 0) {
            errln("%s:%d THREAD INFO: thread %d failed to start with status %d", __FILE__, __LINE__, j, spawnResult);
            return;
        }
    }
    logln("Spawned all");

    for(int32_t i=0;i<kCollatorThreadThreads;i++) {
        tests[i].join();
        //logln(UnicodeString("Test #") + i + " is complete.. ");
    }
}

#endif /* #if !UCONFIG_NO_COLLATION */




//-------------------------------------------------------------------------------------------
//
//   StringThreadTest2
//
//-------------------------------------------------------------------------------------------

const int kStringThreadIterations = 2500;// # of iterations per thread
const int kStringThreadThreads    = 10;  // # of threads to spawn


class StringThreadTest2 : public SimpleThread
{
public:
    int                 fNum;
    int                 fTraceInfo;
    static const UnicodeString *gSharedString;

    StringThreadTest2() // constructor is NOT multithread safe.
        : SimpleThread(),
        fTraceInfo(0)
    {
    };


    virtual void run()
    {
        fTraceInfo    = 1;
        int loopCount = 0;

        for (loopCount = 0; loopCount < kStringThreadIterations; loopCount++) {
            if (*gSharedString != "This is the original test string.") {
                IntlTest::gTest->errln("%s:%d Original string is corrupt.", __FILE__, __LINE__);
                break;
            }
            UnicodeString s1 = *gSharedString;
            s1 += "cat this";
            UnicodeString s2(s1);
            UnicodeString s3 = *gSharedString;
            s2 = s3;
            s3.truncate(12);
            s2.truncate(0);
        }

        fTraceInfo = 2;
    }

};

const UnicodeString *StringThreadTest2::gSharedString = NULL;

// ** The actual test function.


void MultithreadTest::TestString()
{
    int     j;
    StringThreadTest2::gSharedString = new UnicodeString("This is the original test string.");
    StringThreadTest2  tests[kStringThreadThreads];

    logln(UnicodeString("Spawning: ") + kStringThreadThreads + " threads * " + kStringThreadIterations + " iterations each.");
    for(j = 0; j < kStringThreadThreads; j++) {
        int32_t threadStatus = tests[j].start();
        if (threadStatus != 0) {
            errln("%s:%d System Error %d starting thread number %d.", __FILE__, __LINE__, threadStatus, j);
        }
    }

    // Force a failure, to verify test is functioning and can report errors.
    // const_cast<UnicodeString *>(StringThreadTest2::gSharedString)->setCharAt(5, 'x');

    for(j=0; j<kStringThreadThreads; j++) {
        tests[j].join();
        logln(UnicodeString("Test #") + j + " is complete.. ");
    }

    delete StringThreadTest2::gSharedString;
    StringThreadTest2::gSharedString = NULL;
}


//
// Test for ticket #10673, race in cache code in AnyTransliterator.
// It's difficult to make the original unsafe code actually fail, but
// this test will fairly reliably take the code path for races in
// populating the cache.
//

#if !UCONFIG_NO_TRANSLITERATION
Transliterator *gSharedTranslit = NULL;
class TxThread: public SimpleThread {
  public:
    TxThread() {};
    ~TxThread();
    void run();
};

TxThread::~TxThread() {}
void TxThread::run() {
    UnicodeString greekString("\\u03B4\\u03B9\\u03B1\\u03C6\\u03BF\\u03C1\\u03B5\\u03C4\\u03B9\\u03BA\\u03BF\\u03CD\\u03C2");
    greekString = greekString.unescape();
    gSharedTranslit->transliterate(greekString);
    if (greekString[0] != 0x64)      // 'd'. The whole transliterated string is "diaphoretikous" (accented u).
    {
        IntlTest::gTest->errln("%s:%d Transliteration failed.", __FILE__, __LINE__);
    }
}
#endif


void MultithreadTest::TestAnyTranslit() {
#if !UCONFIG_NO_TRANSLITERATION
    UErrorCode status = U_ZERO_ERROR;
    LocalPointer<Transliterator> tx(Transliterator::createInstance("Any-Latin", UTRANS_FORWARD, status));
    if (U_FAILURE(status)) {
        dataerrln("File %s, Line %d: Error, status = %s", __FILE__, __LINE__, u_errorName(status));
        return;
    }
    gSharedTranslit = tx.getAlias();
    TxThread  threads[4];
    int32_t i;
    for (i=0; i<UPRV_LENGTHOF(threads); i++) {
        threads[i].start();
    }

    for (i=0; i<UPRV_LENGTHOF(threads); i++) {
        threads[i].join();
    }
    gSharedTranslit = NULL;
#endif  // !UCONFIG_NO_TRANSLITERATION
}


//
// Condition Variables Test
//   Create a swarm of threads.
//   Using a mutex and a condition variables each thread
//     Increments a global count of started threads.
//     Broadcasts that it has started.
//     Waits on the condition that all threads have started.
//     Increments a global count of finished threads.
//     Waits on the condition that all threads have finished.
//     Exits.
//

class CondThread: public SimpleThread {
  public:
    CondThread() :fFinished(false)  {};
    ~CondThread() {};
    void run();
    bool  fFinished;
};

static UMutex gCTMutex = U_MUTEX_INITIALIZER;
static UConditionVar gCTConditionVar = U_CONDITION_INITIALIZER;
int gConditionTestOne = 1;   // Value one. Non-const, extern linkage to inhibit
                             //   compiler assuming a known value.
int gStartedThreads;
int gFinishedThreads;
static const int NUMTHREADS = 10;


// Worker thread function.
void CondThread::run() {
    umtx_lock(&gCTMutex);
    gStartedThreads += gConditionTestOne;
    umtx_condBroadcast(&gCTConditionVar);

    while (gStartedThreads < NUMTHREADS) {
        if (gFinishedThreads != 0) {
            IntlTest::gTest->errln("File %s, Line %d: Error, gStartedThreads = %d, gFinishedThreads = %d",
                             __FILE__, __LINE__, gStartedThreads, gFinishedThreads);
        }
        umtx_condWait(&gCTConditionVar, &gCTMutex);
    }

    gFinishedThreads += gConditionTestOne;
    fFinished = true;
    umtx_condBroadcast(&gCTConditionVar);

    while (gFinishedThreads < NUMTHREADS) {
        umtx_condWait(&gCTConditionVar, &gCTMutex);
    }
    umtx_unlock(&gCTMutex);
}

void MultithreadTest::TestConditionVariables() {
    gStartedThreads = 0;
    gFinishedThreads = 0;
    int i;

    umtx_lock(&gCTMutex);
    CondThread *threads[NUMTHREADS];
    for (i=0; i<NUMTHREADS; ++i) {
        threads[i] = new CondThread;
        threads[i]->start();
    }

    while (gStartedThreads < NUMTHREADS) {
        umtx_condWait(&gCTConditionVar, &gCTMutex);
    }

    while (gFinishedThreads < NUMTHREADS) {
        umtx_condWait(&gCTConditionVar, &gCTMutex);
    }

    umtx_unlock(&gCTMutex);

    for (i=0; i<NUMTHREADS; ++i) {
        if (!threads[i]->fFinished) {
            errln("File %s, Line %d: Error, threads[%d]->fFinished == false", __FILE__, __LINE__, i);
        }
    }

    for (i=0; i<NUMTHREADS; ++i) {
        threads[i]->join();
        delete threads[i];
    }
}


//
// Unified Cache Test
//

static const char *gCacheLocales[] = {"en_US", "en_GB", "fr_FR", "fr"};
static int32_t gObjectsCreated = 0;  // protected by gCTMutex
static const int32_t CACHE_LOAD = 3;

class UCTMultiThreadItem : public SharedObject {
  public:
    char *value;
    UCTMultiThreadItem(const char *x) : value(NULL) {
        value = uprv_strdup(x);
    }
    virtual ~UCTMultiThreadItem() {
        uprv_free(value);
    }
};

U_NAMESPACE_BEGIN

template<> U_EXPORT
const UCTMultiThreadItem *LocaleCacheKey<UCTMultiThreadItem>::createObject(
        const void * /*unused*/, UErrorCode & /* status */) const {
    umtx_lock(&gCTMutex);
    bool firstObject = (gObjectsCreated == 0);
    if (firstObject) {
        // Force the first object creation that comes through to wait
        // until other have completed. Verifies that cache doesn't
        // deadlock when a creation is slow.

        // Note that gObjectsCreated needs to be incremeneted from 0 to 1
        // early, to keep subsequent threads from entering this path.
        gObjectsCreated = 1;
        while (gObjectsCreated < 3) {
            umtx_condWait(&gCTConditionVar, &gCTMutex);
        }
    }
    umtx_unlock(&gCTMutex);

    UCTMultiThreadItem *result = new UCTMultiThreadItem(fLoc.getName());
    result->addRef();

    // Log that we created an object. The first object was already counted,
    //    don't do it again.
    umtx_lock(&gCTMutex);
    if (!firstObject) {
        gObjectsCreated += 1;
    }
    umtx_condBroadcast(&gCTConditionVar);
    umtx_unlock(&gCTMutex);
    return result;
}

U_NAMESPACE_END

class UnifiedCacheThread: public SimpleThread {
  public:
    UnifiedCacheThread(const char *loc) : fLoc(loc) {};
    ~UnifiedCacheThread() {};
    void run();
    const char *fLoc;
};

void UnifiedCacheThread::run() {
    UErrorCode status = U_ZERO_ERROR;
    const UnifiedCache *cache = UnifiedCache::getInstance(status);
    U_ASSERT(status == U_ZERO_ERROR);
    const UCTMultiThreadItem *item = NULL;
    cache->get(LocaleCacheKey<UCTMultiThreadItem>(fLoc), item, status);
    U_ASSERT(item != NULL);
    if (uprv_strcmp(fLoc, item->value)) {
      IntlTest::gTest->errln("Expected %s, got %s", fLoc, item->value);
    }
    item->removeRef();
}

void MultithreadTest::TestUnifiedCache() {
    UErrorCode status = U_ZERO_ERROR;
    const UnifiedCache *cache = UnifiedCache::getInstance(status);
    U_ASSERT(cache != NULL);
    cache->flush();
    gFinishedThreads = 0;
    gObjectsCreated = 0;

    UnifiedCacheThread *threads[CACHE_LOAD][UPRV_LENGTHOF(gCacheLocales)];
    for (int32_t i=0; i<CACHE_LOAD; ++i) {
        for (int32_t j=0; j<UPRV_LENGTHOF(gCacheLocales); ++j) {
            threads[i][j] = new UnifiedCacheThread(gCacheLocales[j]);
            threads[i][j]->start();
        }
    }

    for (int32_t i=0; i<CACHE_LOAD; ++i) {
        for (int32_t j=0; j<UPRV_LENGTHOF(gCacheLocales); ++j) {
            threads[i][j]->join();
        }
    }
    assertEquals("Objects created", UPRV_LENGTHOF(gCacheLocales), gObjectsCreated);

    // clean up threads
    for (int32_t i=0; i<CACHE_LOAD; ++i) {
        for (int32_t j=0; j<UPRV_LENGTHOF(gCacheLocales); ++j) {
            delete threads[i][j];
        }
    }
}


//
//  BreakTransliterator Threading Test
//     This is a test for bug #11603. Test verified to fail prior to fix.
//

static const Transliterator *gSharedTransliterator;
static const UnicodeString *gTranslitInput;
static const UnicodeString *gTranslitExpected;

class BreakTranslitThread: public SimpleThread {
  public:
    BreakTranslitThread() {};
    ~BreakTranslitThread() {};
    void run();
};

void BreakTranslitThread::run() {
    for (int i=0; i<10; i++) {
        icu::UnicodeString s(*gTranslitInput);
        gSharedTransliterator->transliterate(s);
        if (*gTranslitExpected != s) {
            IntlTest::gTest->errln("%s:%d Transliteration threading failure.", __FILE__, __LINE__);
            break;
        }
    }
}

void MultithreadTest::TestBreakTranslit() {
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString input(
        "\\u0E42\\u0E14\\u0E22\\u0E1E\\u0E37\\u0E49\\u0E19\\u0E10\\u0E32\\u0E19\\u0E41\\u0E25\\u0E49\\u0E27,");
    input = input.unescape();
    gTranslitInput = &input;

    gSharedTransliterator = Transliterator::createInstance(
        UNICODE_STRING_SIMPLE("Any-Latin; Lower; NFD; [:Diacritic:]Remove; NFC; Latin-ASCII;"), UTRANS_FORWARD, status);
    TSMTHREAD_ASSERT_SUCCESS(status); 

    UnicodeString expected(*gTranslitInput);
    gSharedTransliterator->transliterate(expected);
    gTranslitExpected = &expected;

    BreakTranslitThread threads[4];
    for (int i=0; i<UPRV_LENGTHOF(threads); ++i) {
        threads[i].start();
    }
    for (int i=0; i<UPRV_LENGTHOF(threads); ++i) {
        threads[i].join();
    }

    delete gSharedTransliterator;
    gTranslitInput = NULL;
    gTranslitExpected = NULL;
}
