/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-2003, 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 "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)
{
  TestLog testLog;

  driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", testLog, 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 */
