/***********************************************************************
 * Copyright (C) 2016 and later: Unicode, Inc. and others.
 * License & terms of use: http://www.unicode.org/copyright.html#License
 *
 ***********************************************************************
 ***********************************************************************
 * COPYRIGHT:
 * Copyright (C) 2001-2016 International Business Machines Corporation
 * and others. All Rights Reserved.
 *
 ***********************************************************************/
/********************************************************************************
*
* File ubrkperf.cpp
*
* Modification History:
*        Name                     Description
*     Vladimir Weinstein          First Version, based on collperf
*
*********************************************************************************
*/

#include "cmemory.h"
#include "ubrkperf.h"
#include "uoptions.h"
#include <stdio.h>


#if 0
#if U_PLATFORM_IS_DARWIN_BASED
#include <ApplicationServices/ApplicationServices.h>
enum{
  kUCTextBreakAllMask = (kUCTextBreakClusterMask | kUCTextBreakWordMask | kUCTextBreakLineMask)
    };
UCTextBreakType breakTypes[4] = {kUCTextBreakCharMask, kUCTextBreakClusterMask, kUCTextBreakWordMask, kUCTextBreakLineMask};
TextBreakLocatorRef breakRef;
UCTextBreakType macBreakType;

void createMACBrkIt() {
  OSStatus status = noErr;
  LocaleRef lref;
  status = LocaleRefFromLocaleString(opt_locale, &lref);
  status = UCCreateTextBreakLocator(lref, 0, kUCTextBreakAllMask, (TextBreakLocatorRef*)&breakRef);
  if(opt_char == TRUE) {
    macBreakType = kUCTextBreakClusterMask;
  } else if(opt_word == TRUE) {
    macBreakType = kUCTextBreakWordMask;
  } else if(opt_line == TRUE) {
    macBreakType = kUCTextBreakLineMask;
  } else if(opt_sentence == TRUE) {
    // error
    // brkit = BreakIterator::createSentenceInstance(opt_locale, status);
  } else {
    // default is character iterator
    macBreakType = kUCTextBreakClusterMask;
      }
}
#endif


void doForwardTest() {
  if (opt_terse == FALSE) {
    printf("Doing the forward test\n");
  }
  int32_t noBreaks = 0;
  int32_t i = 0;
  unsigned long startTime = timeGetTime();
  unsigned long elapsedTime = 0;
  if(opt_icu) {
    createICUBrkIt();
    brkit->setText(text);
    brkit->first();
    if (opt_terse == FALSE) {
      printf("Warmup\n");
    }
    while(brkit->next() != BreakIterator::DONE) {
      noBreaks++;
    }
  
    if (opt_terse == FALSE) {
      printf("Measure\n");
    } 
    startTime = timeGetTime();
    for(i = 0; i < opt_loopCount; i++) {
      brkit->first();  
      while(brkit->next() != BreakIterator::DONE) {
      }
    }

    elapsedTime = timeGetTime()-startTime;
  } else if(opt_mac) {
#if U_PLATFORM_IS_DARWIN_BASED
    createMACBrkIt();
    UniChar* filePtr = text;
    OSStatus status = noErr;
    UniCharCount startOffset = 0, breakOffset = 0, numUniChars = textSize;
    startOffset = 0;
    //printf("\t---Search forward--\n");
			
    while (startOffset < numUniChars)
    {
	status = UCFindTextBreak(breakRef, macBreakType, kUCTextBreakLeadingEdgeMask, filePtr, numUniChars,
                               startOffset, &breakOffset);
      //require_action(status == noErr, EXIT, printf( "**UCFindTextBreak failed: startOffset %d, status %d\n", (int)startOffset, (int)status));
      //require_action((breakOffset <= numUniChars),EXIT, printf("**UCFindTextBreak breakOffset too big: startOffset %d, breakOffset %d\n", (int)startOffset, (int)breakOffset));
				
      // Output break
      //printf("\t%d\n", (int)breakOffset);
				
      // Increment counters
	noBreaks++;
      startOffset = breakOffset;
    }
    startTime = timeGetTime();
    for(i = 0; i < opt_loopCount; i++) {
      startOffset = 0;
			
      while (startOffset < numUniChars)
	{
	  status = UCFindTextBreak(breakRef, macBreakType, kUCTextBreakLeadingEdgeMask, filePtr, numUniChars,
				   startOffset, &breakOffset);
	  // Increment counters
	  startOffset = breakOffset;
	}
    }
    elapsedTime = timeGetTime()-startTime;
    UCDisposeTextBreakLocator(&breakRef);
#endif


  }


  if (opt_terse == FALSE) {
  int32_t loopTime = (int)(float(1000) * ((float)elapsedTime/(float)opt_loopCount));
      int32_t timePerCU = (int)(float(1000) * ((float)loopTime/(float)textSize));
      int32_t timePerBreak = (int)(float(1000) * ((float)loopTime/(float)noBreaks));
      printf("forward break iteration average loop time %d\n", loopTime);
      printf("number of code units %d average time per code unit %d\n", textSize, timePerCU);
      printf("number of breaks %d average time per break %d\n", noBreaks, timePerBreak);
  } else {
      printf("time=%d\nevents=%d\nsize=%d\n", elapsedTime, noBreaks, textSize);
  }


}




#endif

UPerfFunction* BreakIteratorPerformanceTest::TestICUForward()
{
  return new ICUForward(locale, m_mode_, m_file_, m_fileLen_);
}

UPerfFunction* BreakIteratorPerformanceTest::TestICUIsBound()
{
  return new ICUIsBound(locale, m_mode_, m_file_, m_fileLen_);
}

UPerfFunction* BreakIteratorPerformanceTest::TestDarwinForward()
{
  return NULL;
}

UPerfFunction* BreakIteratorPerformanceTest::TestDarwinIsBound()
{
  return NULL;
}

UPerfFunction* BreakIteratorPerformanceTest::runIndexedTest(int32_t index, UBool exec,
												   const char *&name, 
												   char* par) 
{
    switch (index) {
        TESTCASE(0, TestICUForward);
		TESTCASE(1, TestICUIsBound);
		TESTCASE(2, TestDarwinForward);
		TESTCASE(3, TestDarwinIsBound);
        default: 
            name = ""; 
            return NULL;
    }
    return NULL;
}

UOption options[]={
                      UOPTION_DEF( "mode",        'm', UOPT_REQUIRES_ARG)
                  };


BreakIteratorPerformanceTest::BreakIteratorPerformanceTest(int32_t argc, const char* argv[], UErrorCode& status)
: UPerfTest(argc,argv,status),
m_mode_(NULL),
m_file_(NULL),
m_fileLen_(0)
{

    _remainingArgc = u_parseArgs(_remainingArgc, (char**)argv, UPRV_LENGTHOF(options), options);


    if(options[0].doesOccur) {
      m_mode_ = options[0].value;
      switch(options[0].value[0]) {
      case 'w' : 
      case 'c' :
      case 's' :
      case 'l' :
        break;
      default:
        status = U_ILLEGAL_ARGUMENT_ERROR;
        break;
      }
    } else {
      status = U_ILLEGAL_ARGUMENT_ERROR;
    }

    m_file_ = getBuffer(m_fileLen_, status);

    if(status== U_ILLEGAL_ARGUMENT_ERROR){
       fprintf(stderr, gUsageString, "ubrkperf");
       fprintf(stderr, "\t-m or --mode        Required mode for breakiterator: char, word, line or sentence\n");

       return;
    }

    if(U_FAILURE(status)){
        fprintf(stderr, "FAILED to create UPerfTest object. Error: %s\n", u_errorName(status));
        return;
    }
}

BreakIteratorPerformanceTest::~BreakIteratorPerformanceTest()
{
}


//----------------------------------------------------------------------------------------
//
//    Main   --  process command line, read in and pre-process the test file,
//                 call other functions to do the actual tests.
//
//----------------------------------------------------------------------------------------
int main(int argc, const char** argv) {
    UErrorCode status = U_ZERO_ERROR;
    BreakIteratorPerformanceTest test(argc, argv, status);
    if(U_FAILURE(status)){
        return status;
    }
    if(test.run()==FALSE){
        fprintf(stderr,"FAILED: Tests could not be run please check the arguments.\n");
        return -1;
    }
    return 0;
}
