/*
 *******************************************************************************
 * Copyright (C) 2005-2007, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************

 *******************************************************************************
 */

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

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.TestUtil;
import com.ibm.icu.text.IDNA;
import com.ibm.icu.text.StringPrepParseException;
import com.ibm.icu.text.UTF16;

/**
 * @author limaoyu
 * 
 */
public class IDNAConformanceTest extends TestFmwk {

    public static void main(String[] args) throws Exception {
        new IDNAConformanceTest().run(args);
    }

    public void TestConformance() {

        TreeMap inputData = null;
        
        try {
            inputData = ReadInput.getInputData();
        } catch (UnsupportedEncodingException e) {
            errln(e.getMessage());
            return;
        } catch (IOException e) {
            errln(e.getMessage());
            return;
        }
        
        Set keyMap = inputData.keySet();
        for (Iterator iter = keyMap.iterator(); iter.hasNext();) {
            Long element = (Long) iter.next();
            HashMap tempHash = (HashMap) inputData.get(element);

            //get all attributes from input data
            String passfail = (String) tempHash.get("passfail");
            String desc = (String) tempHash.get("desc");
            String type = (String) tempHash.get("type");
            String namebase = (String) tempHash.get("namebase");
            String nameutf8 = (String) tempHash.get("nameutf8");
            String namezone = (String) tempHash.get("namezone");
            String failzone1 = (String) tempHash.get("failzone1");
            String failzone2 = (String) tempHash.get("failzone2");

            //they maybe includes <*> style unicode
            namebase = stringReplace(namebase);
            namezone = stringReplace(namezone);

            String result = null;
            boolean failed = false;

            if ("toascii".equals(tempHash.get("type"))) {
                
                //get the result
                try {
                    //by default STD3 rules are not used, but if the description
                    //includes UseSTD3ASCIIRules, we will set it.
                    if (desc.toLowerCase().indexOf(
                            "UseSTD3ASCIIRules".toLowerCase()) == -1) {
                        result = IDNA.convertIDNToASCII(namebase,
                                IDNA.ALLOW_UNASSIGNED).toString();
                    } else {
                        result = IDNA.convertIDNToASCII(namebase,
                                IDNA.USE_STD3_RULES).toString();
                    }
                } catch (StringPrepParseException e2) {
                    //errln(e2.getMessage());
                    failed = true;
                }
                
                
                if ("pass".equals(passfail)) {
                    if (!namezone.equals(result)) {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);                        
                        errln("\t pass fail standard is pass, but failed");
                    } else {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);
                        logln("\tpassed");
                    }
                }

                if ("fail".equals(passfail)) {
                    if (failed) {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);
                        logln("passed");
                    } else {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);                        
                        errln("\t pass fail standard is fail, but no exception thrown out");
                    }
                }
            } else if ("tounicode".equals(tempHash.get("type"))) {
                try {
                    //by default STD3 rules are not used, but if the description
                    //includes UseSTD3ASCIIRules, we will set it.
                    if (desc.toLowerCase().indexOf(
                            "UseSTD3ASCIIRules".toLowerCase()) == -1) {
                        result = IDNA.convertIDNToUnicode(namebase,
                                IDNA.ALLOW_UNASSIGNED).toString();
                    } else {
                        result = IDNA.convertIDNToUnicode(namebase,
                                IDNA.USE_STD3_RULES).toString();
                    }
                } catch (StringPrepParseException e2) {
                    //errln(e2.getMessage());
                    failed = true;
                }
                if ("pass".equals(passfail)) {
                    if (!namezone.equals(result)) {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);
                        
                        errln("\t Did not get the expected result. Expected: " + prettify(namezone) + " Got: " + prettify(result));
                    } else {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);                        
                        logln("\tpassed");
                    }
                }

                if ("fail".equals(passfail)) {
                    if (failed || namebase.equals(result)) {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);
                        
                        logln("\tpassed");
                    } else {
                        printInfo(desc, namebase, nameutf8, namezone,
                                failzone1, failzone2, result, type, passfail);
                        
                        errln("\t pass fail standard is fail, but no exception thrown out");
                    }
                }
            } else {
                continue;
            }
        }
    }

    /**
     * Print log message.
     * @param desc
     * @param namebase
     * @param nameutf8
     * @param namezone
     * @param failzone1
     * @param failzone2
     * @param result
     */
    private void printInfo(String desc, String namebase,
            String nameutf8, String namezone, String failzone1,
            String failzone2, String result, String type, String passfail) {
        logln("desc:\t" + desc);
        log("\t");
        logln("type:\t" + type);
        log("\t");
        logln("pass fail standard:\t" + passfail);
        log("\t");
        logln("namebase:\t" + namebase);
        log("\t");
        logln("nameutf8:\t" + nameutf8);
        log("\t");
        logln("namezone:\t" + namezone);
        log("\t");
        logln("failzone1:\t" + failzone1);
        log("\t");
        logln("failzone2:\t" + failzone2);
        log("\t");
        logln("result:\t" + result);
    }

    /**
     * Change unicode string from <00AD> to \u00AD, for the later is accepted
     * by Java
     * @param str String including <*> style unicode
     * @return \\u String
     */
    private static String stringReplace(String str) {

        StringBuffer result = new StringBuffer();
        char[] chars = str.toCharArray();
        StringBuffer sbTemp = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            if ('<' == chars[i]) {
                sbTemp = new StringBuffer();
                while ('>' != chars[i + 1]) {
                    sbTemp.append(chars[++i]);
                }
                /*
                 * The unicode sometimes is larger then \uFFFF, so have to use
                 * UTF16.
                 */
                int toBeInserted = Integer.parseInt(sbTemp.toString(), 16);
                if ((toBeInserted >> 16) == 0) {
                    result.append((char) toBeInserted);
                } else {
                    String utf16String = UTF16.valueOf(toBeInserted);
                    char[] charsTemp = utf16String.toCharArray();
                    for (int j = 0; j < charsTemp.length; j++) {
                        result.append((char) charsTemp[j]);
                    }
                }
            } else if ('>' == chars[i]) {//end when met with '>'
                continue;
            } else {
                result.append(chars[i]);
            }

        }
        return result.toString();
    }

    /**
     * This class is used to read test data from TestInput file.
     * 
     * @author limaoyu
     *  
     */
    public static class ReadInput {

        public static TreeMap getInputData() throws IOException,
                UnsupportedEncodingException {

            TreeMap result = new TreeMap();
            try {
                BufferedReader in = TestUtil.getDataReader("IDNATestInput.txt", "utf-8");

                String tempStr = null;
                int records = 0;
                boolean firstLine = true;
                HashMap hashItem = new HashMap();

                while ((tempStr = in.readLine()) != null) {
                    //ignore the first line if it's "====="
                    if (firstLine) {
                        if ("=====".equals(tempStr))
                            continue;
                        firstLine = false;
                    }

                    //Ignore empty line
                    if ("".equals(tempStr)) {
                        continue;
                    }

                    String attr = "";//attribute
                    String body = "";//value

                    //get attr and body from line input, and then set them into each hash item.                    
                    int postion = tempStr.indexOf(":");
                    if (postion > -1) {
                        attr = tempStr.substring(0, postion).trim();
                        body = tempStr.substring(postion + 1).trim();

                        //deal with combination lines when end with '\'
                        while (null != body && body.length() > 0
                                && '\\' == body.charAt(body.length() - 1)) {
                            body = body.substring(0, body.length() - 1);
                            body += "\n";
                            tempStr = in.readLine();
                            body += tempStr;
                        }
                    }
                    //push them to hash item
                    hashItem.put(attr, body);

                    //if met "=====", it means this item is finished
                    if ("=====".equals(tempStr)) {
                        //set them into result, using records number as key
                        result.put(new Long(records), hashItem);
                        //create another hash item and continue
                        hashItem = new HashMap();
                        records++;
                        continue;
                    }
                }
            } catch (UnsupportedEncodingException e) {
                throw e;
            } catch (FileNotFoundException e) {
                throw e;
            } catch (IOException e) {
                throw e;
            }
            return result;
        }
    }
}