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

/**
 * IntlTestCollator is the medium level test class for everything in the directory "collate".
 */

/***********************************************************************
* Modification history
* Date        Name        Description
* 02/14/2001  synwee      Compare with cintltst and commented away tests 
*                         that are not run.
***********************************************************************/

#include "unicode/utypes.h"

#if !UCONFIG_NO_COLLATION

#include "unicode/uchar.h"
#include "unicode/tstdtmod.h"
#include "cstring.h"
#include "ucol_tok.h"
#include "tscoll.h"
#include "dadrcoll.h"

U_CDECL_BEGIN
static void U_CALLCONV deleteSeqElement(void *elem) {
  delete((SeqElement *)elem);
}
U_CDECL_END

DataDrivenCollatorTest::DataDrivenCollatorTest() 
: seq(StringCharacterIterator("")),
status(U_ZERO_ERROR),
sequences(status)
{
  driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", *this, status);
  sequences.setDeleter(deleteSeqElement);
}

DataDrivenCollatorTest::~DataDrivenCollatorTest() 
{
  delete driver;
}

void DataDrivenCollatorTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par */)
{
  if(driver != NULL) {
    if (exec)
    {
        logln("TestSuite Collator: ");
    }
    const DataMap *info = NULL;
    TestData *testData = driver->createTestData(index, status);
    if(U_SUCCESS(status)) {
      name = testData->getName();
      if(testData->getInfo(info, status)) {
        log(info->getString("Description", status));
      }
      if(exec) {
        log(name);
          logln("---");
          logln("");
          processTest(testData);
      }
      delete testData;
    } else {
      name = "";
    }
  } else {
    errln("collate/DataDrivenTest data not initialized!");
    name = "";
  }


}

UBool
DataDrivenCollatorTest::setTestSequence(const UnicodeString &setSequence, SeqElement &el) {
  seq.setText(setSequence);
  return getNextInSequence(el);
}

// Parses the sequence to be tested
UBool 
DataDrivenCollatorTest::getNextInSequence(SeqElement &el) {
  el.source.truncate(0);
  UBool quoted = FALSE;
  UBool quotedsingle = FALSE;
  UChar32 currChar = 0;

  while(currChar != CharacterIterator::DONE) {
    currChar= seq.next32PostInc();
    if(!quoted) {
      if(u_isWhitespace(currChar)) {
        continue;
      }
      switch(currChar) {
      case CharacterIterator::DONE:
        break;
      case 0x003C /* < */:
        el.relation = Collator::LESS;
        currChar = CharacterIterator::DONE;
        break;
      case 0x003D /* = */:
        el.relation = Collator::EQUAL;
        currChar = CharacterIterator::DONE;
        break;
      case 0x003E /* > */:
        el.relation = Collator::GREATER;
        currChar = CharacterIterator::DONE;
        break;
      case 0x0027 /* ' */: /* very basic quoting */
        quoted = TRUE;
        quotedsingle = FALSE;
        break;
      case 0x005c /* \ */: /* single quote */
        quoted = TRUE;
        quotedsingle = TRUE;
        break;
      default:
        el.source.append(currChar);
      }
    } else {
      if(currChar == CharacterIterator::DONE) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        errln("Quote in sequence not closed!");
        return FALSE;
      } else if(currChar == 0x0027) {
        quoted = FALSE;
      } else {
        el.source.append(currChar);
      }
      if(quotedsingle) {
        quoted = FALSE;
      }
    }
  }
  return seq.hasNext();
}

// Reads the options string and sets appropriate attributes in collator
void 
DataDrivenCollatorTest::processArguments(Collator *col, const UChar *start, int32_t optLen) {
  const UChar *end = start+optLen;
  UColAttribute attrib;
  UColAttributeValue value;

  if(optLen == 0) {
    return;
  }

  start = ucol_tok_getNextArgument(start, end, &attrib, &value, &status);
  while(start != NULL) {
    if(U_SUCCESS(status)) {
      col->setAttribute(attrib, value, status);
    }
    start = ucol_tok_getNextArgument(start, end, &attrib, &value, &status);
  }
}

void 
DataDrivenCollatorTest::processTest(TestData *testData) {
  Collator *col = NULL;
  const UChar *arguments = NULL;
  int32_t argLen = 0;
  const DataMap *settings = NULL;
  const DataMap *currentCase = NULL;
  UErrorCode intStatus = U_ZERO_ERROR;
  UnicodeString testSetting;
  while(testData->nextSettings(settings, status)) {
    intStatus = U_ZERO_ERROR;
    // try to get a locale
    testSetting = settings->getString("TestLocale", intStatus);
    if(U_SUCCESS(intStatus)) {
      char localeName[256];
      testSetting.extract(0, testSetting.length(), localeName, "");
      col = Collator::createInstance(localeName, status);
      if(U_SUCCESS(status)) {
        logln("Testing collator for locale "+testSetting);
      } else {
        errln("Unable to instantiate collator for locale "+testSetting);
        return;
      }
    } else {
      // if no locale, try from rules
      intStatus = U_ZERO_ERROR;
      testSetting = settings->getString("Rules", intStatus);
      if(U_SUCCESS(intStatus)) {
        col = new RuleBasedCollator(testSetting, status);
        if(U_SUCCESS(status)) {
          logln("Testing collator for rules "+testSetting);
        } else {
          errln("Unable to instantiate collator for rules "+testSetting);
          return;
        }
      } else {
        errln("No collator definition!");
      }
    }
    if(col != NULL) {
      // get attributes
      testSetting = settings->getString("Arguments", intStatus);
      if(U_SUCCESS(intStatus)) {
        logln("Arguments: "+testSetting);
        argLen = testSetting.length();
        arguments = testSetting.getBuffer();
        processArguments(col, arguments, argLen);
        if(U_FAILURE(status)) {
          errln("Couldn't process arguments");
          break;
        }
      } else {
        intStatus = U_ZERO_ERROR;
      }
      // Start the processing
      while(testData->nextCase(currentCase, status)) {
        UnicodeString sequence = currentCase->getString("sequence", status);
        if(U_SUCCESS(status)) {
            processSequence(col, sequence);
        }
      }
    } else {
      errln("Couldn't instantiate a collator!");
    }
    delete col;
    col = NULL;
  }
}

void 
DataDrivenCollatorTest::processSequence(Collator* col, const UnicodeString &sequence) {
  Collator::EComparisonResult relation = Collator::EQUAL;
  UBool hasNext;
  SeqElement *source = NULL;
  SeqElement *target = NULL;
  int32_t j = 0;

  sequences.removeAllElements();

  target = new SeqElement(); 

  setTestSequence(sequence, *target);
  sequences.addElement(target, status);

  do {
    relation = Collator::EQUAL;
    target = new SeqElement(); 
    hasNext = getNextInSequence(*target);
    for(j = sequences.size(); j > 0; j--) {
      source = (SeqElement *)sequences.elementAt(j-1);
      if(relation == Collator::EQUAL && source->relation != Collator::EQUAL) {
        relation = source->relation;
      }
      doTest(col, source->source, target->source, relation);     
    }
    sequences.addElement(target, status);
    source = target;
  } while(hasNext);
}

#endif /* #if !UCONFIG_NO_COLLATION */
