/*
 *******************************************************************************
 * Copyright (C) 2002-2003, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 * $Source: 
 * $Date: 
 * $Revision: 
 *
 *****************************************************************************************
 */

/** 
 * Port From:   ICU4C v2.1 : collate/CollationRegressionTest
 * Source File: $ICU4CRoot/source/test/intltest/regcoll.cpp
 **/
 
package com.ibm.icu.dev.test.collator;

import com.ibm.icu.dev.test.*;
import com.ibm.icu.text.*;
import java.util.Locale;
import java.io.*;

public class CollationThaiTest extends TestFmwk {
    
    final int MAX_FAILURES_TO_SHOW = 8;
    
    public static void main(String[] args) throws Exception {
        new CollationThaiTest().run(args);
    }
    
    /**
     * Odd corner conditions taken from "How to Sort Thai Without Rewriting Sort",
     * by Doug Cooper, http://seasrc.th.net/paper/thaisort.zip
     */
    public void TestCornerCases() {
        String TESTS[] = {
            // Shorter words precede longer
            "\u0e01",                               "<",    "\u0e01\u0e01",
    
            // Tone marks are considered after letters (i.e. are primary ignorable)
            "\u0e01\u0e32",                        "<",    "\u0e01\u0e49\u0e32",
    
            // ditto for other over-marks
            "\u0e01\u0e32",                        "<",    "\u0e01\u0e32\u0e4c",
    
            // commonly used mark-in-context order.
            // In effect, marks are sorted after each syllable.
            "\u0e01\u0e32\u0e01\u0e49\u0e32",   "<",    "\u0e01\u0e48\u0e32\u0e01\u0e49\u0e32",
    
            // Hyphens and other punctuation follow whitespace but come before letters
            "\u0e01\u0e32",                        "<",    "\u0e01\u0e32-",
            "\u0e01\u0e32-",                       "<",    "\u0e01\u0e32\u0e01\u0e32",
    
            // Doubler follows an indentical word without the doubler
            "\u0e01\u0e32",                        "<",    "\u0e01\u0e32\u0e46",
            "\u0e01\u0e32\u0e46",                 "<",    "\u0e01\u0e32\u0e01\u0e32",
    
            // \u0e45 after either \u0e24 or \u0e26 is treated as a single
            // combining character, similar to "c < ch" in traditional spanish.
            // TODO: beef up this case
            "\u0e24\u0e29\u0e35",                 "<",    "\u0e24\u0e45\u0e29\u0e35",
            "\u0e26\u0e29\u0e35",                 "<",    "\u0e26\u0e45\u0e29\u0e35",
    
            // Vowels reorder, should compare \u0e2d and \u0e34
            "\u0e40\u0e01\u0e2d",                 "<",    "\u0e40\u0e01\u0e34",
    
            // Tones are compared after the rest of the word (e.g. primary ignorable)
            "\u0e01\u0e32\u0e01\u0e48\u0e32",   "<",    "\u0e01\u0e49\u0e32\u0e01\u0e32",
    
            // Periods are ignored entirely
            "\u0e01.\u0e01.",                      "<",    "\u0e01\u0e32",
        };
        
        Collator coll = null;
        try {
            coll = Collator.getInstance(new Locale("th", "TH", ""));
        } catch (Exception e) {
            errln("Error: could not construct Thai collator");
            return;
        }
        compareArray(coll, TESTS); 
    }
    
    void compareArray(Collator c, String[] tests) {
        for (int i = 0; i < tests.length; i += 3) {
            int expect = 0;
            if (tests[i+1].equals("<")) {
                expect = -1;
            } else if (tests[i+1].equals(">")) {
                expect = 1;
            } else if (tests[i+1].equals("=")) {
                expect = 0;
            } else {
                // expect = Integer.decode(tests[i+1]).intValue();
                errln("Error: unknown operator " + tests[i+1]);
                return;
            }
            String s1 = tests[i];
            String s2 = tests[i+2];
            int result = c.compare(s1, s2);
            if (sign(result) != sign(expect)) {
                errln("" + i/3 + ": compare(" + s1
                      + " , " + s2  + ") got " + result + "; expected " + expect);
    
                CollationKey k1, k2;
                try {
                    k1 = c.getCollationKey(s1);
                    k2 = c.getCollationKey(s2);
                } catch (Exception e) {
                    errln("Fail: getCollationKey returned ");
                    return;
                }
                errln("  key1: " + prettify(k1));
                errln("  key2: " + prettify(k2));
            } else {
                // Collator.compare worked OK; now try the collation keys
                CollationKey k1, k2;
                try {
                    k1 = c.getCollationKey(s1);
                    k2 = c.getCollationKey(s2);
                } catch (Exception e) {
                    //System.out.println(e);
                    errln("Fail: getCollationKey returned ");
                    return;
                }
    
                result = k1.compareTo(k2);
                if (sign(result) != sign(expect)) {
                    errln("" + i/3 + ": key(" + s1
                          + ").compareTo(key(" + s2
                          + ")) got " + result + "; expected " + expect);
                    
                    errln("  " + prettify(k1) + " vs. " + prettify(k2));
                }
            }
        }
    }
    
    int sign(int i ) {
        if (i < 0) return -1;
        if (i > 0) return 1;
        return 0;
    }
    
    /**
     * Read the external dictionary file, which is already in proper
     * sorted order, and confirm that the collator compares each line as
     * preceding the following line.
     */
    public void TestDictionary() {
        Collator coll = null;
        try {
            coll = Collator.getInstance(new Locale("th", "TH", ""));
        } catch (Exception e) {
            errln("Error: could not construct Thai collator");
            return;
        }
     
        // Read in a dictionary of Thai words
        DataInputStream in = null;
        String fileName = "th18057.txt";
        try {
            in = new DataInputStream(new FileInputStream(TestUtil.getDataFile(
                                                                   fileName)));
        } catch (Exception e) {
            try {
                in.close();
            } catch (IOException ioe) {}
            errln("Error: could not open test file: " + fileName);
            return;        
        }
    
        stripBOM(in);
        
        //
        // Loop through each word in the dictionary and compare it to the previous
        // word.  They should be in sorted order.
        //
        String lastWord = "";
        int line = 0;
        int failed = 0;
        int wordCount = 0;
        String word = readLine(in);
        while (word != null) {
            line++;
    
            // Skip comments and blank lines
            if (word.length() == 0 || word.charAt(0) == 0x23) {
                word = readLine(in);
                continue;
            }
    
            // Show the first 8 words being compared, so we can see what's happening
            ++wordCount;
            if (wordCount <= 8) {
                logln("Word " + wordCount + ": " + word);
            }
    
            if (lastWord.length() > 0) {
                int result = 0;
                try {
                    CollationIteratorTest.backAndForth(this, 
                        ((RuleBasedCollator)coll).getCollationElementIterator(
                                                                    lastWord));
                    CollationIteratorTest.backAndForth(this, 
                        ((RuleBasedCollator)coll).getCollationElementIterator(
                                                                        word));
                    result = coll.compare(lastWord, word);
                } catch (Exception e) {
                    logln("line" + line + ":" + word);
                    logln("lastWord = " + lastWord);
                    logln(e.getMessage());
                }
        
                if (result >= 0) {
                    failed++;
                    if (MAX_FAILURES_TO_SHOW < 0 || failed <= MAX_FAILURES_TO_SHOW) {
                        String msg = "--------------------------------------------\n"
                                    + line
                                    + " compare(" + lastWord
                                    + ", " + word + ") returned " + result
                                    + ", expected -1\n";
                        CollationKey k1, k2;
                        try {
                            k1 = coll.getCollationKey(lastWord);
                            k2 = coll.getCollationKey(word);
                        } catch (Exception e) {
                            errln("Fail: getCollationKey returned ");
                            return;
                        }
                        msg += "key1: " + prettify(k1) + "\n"
                                    + "key2: " + prettify(k2);
                        errln(msg);
                    }
                }
            }
            lastWord = word;
            word = readLine(in);
        }
    
        if (failed != 0) {
            if (failed > MAX_FAILURES_TO_SHOW) {
                errln("Too many failures; only the first " +
                      MAX_FAILURES_TO_SHOW + " failures were shown");
            }
            errln("Summary: " + failed + " of " + (line - 1) +
                  " comparisons failed");
        }
    
        logln("Words checked: " + wordCount);
    }
    
    private static final byte BOM[] = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
    
    private byte savedBytes[]= new byte[BOM.length];
    private int  savedByteCount = 0;
    private int  savedByte = 0;
    
    void stripBOM(DataInputStream in) {
        try {
            savedByteCount = in.read(savedBytes, 0, BOM.length);
            
            for (int i = 0; i < BOM.length; i += 1) {
                if (savedBytes[i] != BOM[i]) {
                    return;
                }
            }
            
            savedByteCount = 0;
            savedByte = 0;
        } catch (EOFException ee) {
            // nothing
        } catch (IOException e) {
            // nothing
        }
    }
    
    String readLine(DataInputStream in) {
        byte[] bytes = new byte[128];
        int i = 0;
        byte c = 0;
        
        while (i < 128) {
            if (savedByte < savedByteCount) {
                c = savedBytes[savedByte++];
            } else {
                try {
                    c = in.readByte();
                } catch (EOFException ee) {
                    return null;
                } catch (IOException e) {
                    errln("Cannot read line from the file");
                    return null;
                }
            }
            
            if (c == 0xD) {
                try {
                    c = in.readByte();
                    
                    if (c != 0xA) {
                        savedBytes[0] = c;
                        savedByte = 0;
                        savedByteCount = 1;
                    }
                } catch (EOFException ee) {
                    break;
                } catch (IOException e) {
                    errln("Cannot read line from the file");
                    return null;
                }
                
                break;
            } else if (c == 0xA) {
                break;
            }
            
            bytes[i++] = c;
        }
        
        String line = null;
        
        try {
            line = new String(bytes, 0, i, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            System.out.println(e);
        }
        
        return line;
    }
    
    String prettify(CollationKey sourceKey) {
        int i;
        byte[] bytes= sourceKey.toByteArray();
        String target = "[";
    
        for (i = 0; i < bytes.length; i++) {
            target += Integer.toHexString(bytes[i]);
            target += " ";
        }
        target += "]";
        return target;
    }
}