/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2002-2005, 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.io.IOException;
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";
        StringBuffer name;
        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);
        }
    }
    
}
