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

/**
 * UCAConformanceTest performs conformance tests defined in the data
 * files. ICU ships with stub data files, as the whole test are too 
 * long. To do the whole test, download the test files.
 */

package com.ibm.icu.dev.test.collator;

import java.io.BufferedReader;
import java.util.Locale;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.TestUtil;
import com.ibm.icu.text.CollationKey;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.RuleBasedCollator;
import com.ibm.icu.text.UTF16;

public class UCAConformanceTest extends TestFmwk {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        new UCAConformanceTest().run(args);
    }
    
    public UCAConformanceTest() {
    }
    protected void init()throws Exception{
        UCA = (RuleBasedCollator)Collator.getInstance(
                new Locale("root", "", ""));

        comparer = new UTF16.StringComparator(true, false, UTF16.StringComparator.FOLD_CASE_DEFAULT);
    }
    RuleBasedCollator UCA;
    RuleBasedCollator rbUCA;
    UTF16.StringComparator comparer;
    
    public void TestTableNonIgnorable() {
        setCollNonIgnorable(UCA);
        openTestFile("NON_IGNORABLE");
        conformanceTest(UCA);
    }
    
    public void TestTableShifted() {
        setCollShifted(UCA);
        openTestFile("SHIFTED");
        conformanceTest(UCA);
    }
    
    public void TestRulesNonIgnorable() {
        initRbUCA();
        
        setCollNonIgnorable(rbUCA);
        openTestFile("NON_IGNORABLE");
        conformanceTest(rbUCA);
    }
    
    public void TestRulesShifted() {
        logln("This test is currently disabled, as it is impossible to "+
        "wholly represent fractional UCA using tailoring rules.");
        return;
        /*        initRbUCA();
         
         if(U_SUCCESS(status)) {
         setCollShifted(rbUCA);
         openTestFile("SHIFTED");
         testConformance(rbUCA);
         }
         */
    }
    BufferedReader in;
    private void openTestFile(String type)
    {
        String collationTest = "CollationTest_";
        String ext = ".txt";
        try {
            if(in != null) {
                in.close();
            }
        } catch (Exception e) {
            errln("Could not close the opened file!");
            return;
        }
        try {
            in = TestUtil.getDataReader(collationTest+type+ext);
        } catch (Exception e) {
            try {
                in = TestUtil.getDataReader(collationTest+type+"_SHORT"+ext);
            } catch (Exception e1) {
                try {
                    in = TestUtil.getDataReader(collationTest+type+"_STUB"+ext);
                    logln( "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/");
                } catch (Exception e11) {
                    errln("ERROR: Could not find any of the test files");
                }
            }
        }
    }          
    
    private void setCollNonIgnorable(RuleBasedCollator coll) 
    {
        if(coll != null) {
            coll.setDecomposition(RuleBasedCollator.CANONICAL_DECOMPOSITION);
            coll.setLowerCaseFirst(false);
            coll.setCaseLevel(false);
            coll.setStrength(RuleBasedCollator.TERTIARY);
            coll.setAlternateHandlingShifted(false);
        }
    }
    
    private void setCollShifted(RuleBasedCollator coll) 
    {
        if(coll != null) {
            coll.setDecomposition(RuleBasedCollator.CANONICAL_DECOMPOSITION);
            coll.setLowerCaseFirst(false);
            coll.setCaseLevel(false);
            coll.setStrength(RuleBasedCollator.QUATERNARY);
            coll.setAlternateHandlingShifted(true);
        }
    }
    
    
    
    private void initRbUCA() 
    {
        /*      if(!rbUCA) {
         UParseError parseError;
         UChar      *ucarules = buffer;
         int32_t size = ucol_getRulesEx(UCA, UCOL_FULL_RULES, ucarules, 
         BUFFER_SIZE_);
         if (size > BUFFER_SIZE_) {
         ucarules = (UChar *)malloc(size * sizeof(UChar));
         size = ucol_getRulesEx(UCA, UCOL_FULL_RULES, ucarules, size);
         }
         rbUCA = ucol_openRules(ucarules, size, UCOL_DEFAULT, UCOL_TERTIARY, 
         &parseError, &status);
         if (U_FAILURE(status)) {
         errln("Failure creating UCA rule-based collator: %s", u_errorName(status));
         return;
         }
         }
         */
    }
    
    private String parseString(String line) {
        int i = 0, value;
        StringBuffer result = new StringBuffer(), buffer = new StringBuffer();
        
        for(;;) {
            while(Character.isWhitespace(line.charAt(i))) {
                i++;
            }
            if(line.charAt(i) == ';' || i == line.length()) {
                return result.toString();
            }
            while(Character.isLetterOrDigit(line.charAt(i))) {
                buffer.append(line.charAt(i));
                i++;
            }
            /* read one code point */
            value = Integer.parseInt(buffer.toString(), 16);
            buffer.delete(0, buffer.length());
            
            UTF16.append(result, value);
        }
        
    }
    private void conformanceTest(RuleBasedCollator coll) {
        if(in == null || coll == null) {
            return;
        }
        
        int lineNo = 0;
        
        String line = null, oldLine = null, buffer = null, oldB = null;
        CollationKey oldSk = null, newSk = null;
        
        int res = 0, cmpres = 0, cmpres2 = 0;
        
        try {
            while ((line = in.readLine()) != null) {
                lineNo++;
                if(line.length() < 3 || line.charAt(0) == '#') {
                    continue;
                }
                buffer = parseString(line);
                
                newSk = coll.getCollationKey(buffer);
                if(oldSk != null) {
                    res = oldSk.compareTo(newSk);
                    cmpres = coll.compare(oldB, buffer);
                    cmpres2 = coll.compare(buffer, oldB);
                    
                    if(cmpres != -cmpres2) {
                        errln("Compare result not symmetrical on line "+lineNo);
                    }
                    if(((res&0x80000000) != (cmpres&0x80000000)) || (res == 0 && cmpres != 0) || (res != 0 && cmpres == 0)) {
                        errln("Difference between ucol_strcoll and sortkey compare on line " + lineNo);
                        logln(oldLine);
                        logln(line);
                    }
                    
                    if(res > 0) {
                        errln("Line " + lineNo + " is not greater or equal than previous line");
                        logln(oldLine);
                        logln(line);
                        cmpres = coll.compare(oldB, buffer);
                    } else if(res == 0) {  // equal 
                        res = comparer.compare(oldB, buffer);
                        if (res == 0) {
                            errln("Probable error in test file on line " + lineNo +" (comparing identical strings)");
                            logln(oldLine);
                            logln(line);
                        } else if (res > 0) {
                            errln("Sortkeys are identical, but code point comapare gives >0 on line " + lineNo);
                            logln(oldLine);
                            logln(line);
                        }
                    }
                }
                
                oldSk = newSk;
                oldB = buffer;
                oldLine = line;
            }
        } catch (Exception e) {
            errln("Unexpected exception "+e);
        }
    }
    
}
