/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2002-2006, 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://dev.icu-project.org/cgi-bin/viewcvs.cgi/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);
        }
    }
    
}
