/**
 *******************************************************************************
 * Copyright (C) 2001-2006, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.util;

import java.util.ResourceBundle;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.Utility;


public final class ICUListResourceBundleTest extends TestFmwk 
{
    public static void main(String args[]) throws Exception {
        ICUListResourceBundleTest test = new ICUListResourceBundleTest();
        test.run(args);

    }

    public void TestReferences() {
       // ResourceBundle rb = ICULocaleData.getLocaleElements("th");
        //logln("got rb:" + rb);
        ResourceBundle rb = null;
        byte[] binaryData = null;//(byte[])rb.getObject("%%CollationBin");
        Object colElem = rb.getObject("collations");
        if(colElem instanceof Object[][]){
            Object[][] colElemArr = (Object[][])colElem;
            if(((String)colElemArr[0][0]).equals("%%CollationBin")){   
               binaryData = (byte[]) colElemArr[0][1];
            }
        }else{
            errln("Did not get the expected object");
        }
        logln("got binaryData: " + binaryData + " length: " + (binaryData == null ? 0 : binaryData.length));
        Object[] stringArrayData = (Object[])rb.getObject("collations");
        //String[] collationData = new String[] {
         //   (String)stringArrayData[0],
         //   (String)stringArrayData[0]
        //};
        logln("got stringData: " + stringArrayData + " length: " + stringArrayData.length);
        logln("got stringDataElement: " + stringArrayData[0] + " length: " + stringArrayData.length);
        //System.out.println("got sdee: " + collationData[0]);
        //    System.out.println("char data length: " + stringArrayData.length());
    }
   
   String simpleAlias   = "Open";

   Object[][] zoneTests =  new Object[][]{
                               {
                                    "zoneAlias",
                                    new String[] { 
                                                    "PST",
                                                    "Pacific Standard Time",
                                                    "PST",
                                                    "Pacific Daylight Time",
                                                    "PDT",
                                                    "Los Angeles",
                                                },
                               },
                               {
                                   "zoneAlias1",
                                   new String[] { 
                                                   "America/Denver",
                                                   "Mountain Standard Time",
                                                   "MST",
                                                   "Mountain Daylight Time",
                                                   "MDT",
                                                   "Denver",
                        
                                               },
                               },
                               {
                                   "zoneAlias2",
                                   "America/Denver",
                               },
                           };
    Object[] zoneStrings = new Object[] {
                                new String[] { 
                                    
                                    "PST",
                                    "Pacific Standard Time",
                                    "PST",
                                    "Pacific Daylight Time",
                                    "PDT",
                                    "Los Angeles",
                                
                                },
                                new String[] { 
                                    "America/Los_Angeles",
                                    "Pacific Standard Time",
                                    "PST",
                                    "Pacific Daylight Time",
                                    "PDT",
                                    "Los Angeles",
                                
                                },
                            };
    Object[] testGetStringByIndexAliasing =  new String[] { 
                                                    "PST",
                                                    "Pacific Standard Time",
                                                    "PDT",
                                                    "Los Angeles",
                                                };
    Object[][] testGetStringByKeyAliasing = new Object[][]{
                                                {
                                                    "KeyAlias0PST",
                                                    "PST",
                                                },
                                                {
                                                    "KeyAlias1PacificStandardTime",
                                                    "Pacific Standard Time",
                                                },
                                                {
                                                    "KeyAlias2PDT",
                                                    "PDT",
                                                },
                                                {
                                                    "KeyAlias3LosAngeles",
                                                    "Los Angeles",
                                                },
                                            };                                          
    private boolean arrayEquals(Object[][] s1, Object[][] s2){
        boolean isEqual = true;
        if(s1.length != s2.length){
            return false;
        }
        for (int i = 0; i<s1.length; i++){
            if(s1[i] instanceof Object[][] &&
               s2[i] instanceof Object[][]){
                if(!arrayEquals((Object[][])s1[i],(Object[][]) s2[i])){
                   isEqual = false;
                }
            }else if (s1[i] instanceof Object[] &&
                      s2[i] instanceof Object[]){
                if(!Utility.arrayEquals(s1[i],s2[i])){
                    isEqual = false;
                }
           }else if(s1[i] instanceof Object && s2[i] instanceof Object){
               if(!s1[i].equals(s2[i])){
                   isEqual = false;
               }
           }else{
               isEqual = false;
               break;
           }
        }
        return isEqual;
    }
    
    /* 
    public void TestAliases(){
        ResourceBundle rb = ICULocaleData.getResourceBundle("com.ibm.icu.dev.data","TestDataElements","testaliases");
        //rb.getObject("CollationElements");
        String s1 = rb.getString("simplealias");
        if(s1.equals(simpleAlias)){
            logln("Alias mechanism works for simplealias");
        }else{
            errln("Did not get the expected output for simplealias");
        }
        {
            Object o = null;
            // test aliasing through another alias
            s1 = rb.getString("referencingalias");
            ResourceBundle uk = ICULocaleData.getResourceBundle("com.ibm.icu.impl.data","LocaleElements","uk");
            if(uk instanceof ICUListResourceBundle){
                o = ((ICUListResourceBundle)uk).getObjectWithFallback("collations/standard");
                if(o instanceof Object[][]){
                    Object[][] val = (Object[][]) o;
                    if(s1.equals(val[1][1])){
                        logln("Alias mechanism works for referencingalias");
                    }else{
                        errln("Did not get the expected result for referencingalias");
                    }
                }else{
                    errln("Did not get the expected result for collations resource of uk bundle");
                }
            }
            Object anotheralias = rb.getObject("anotheralias");
            if(anotheralias instanceof Object[][]&& o instanceof Object[][]){
                if(arrayEquals((Object[][])o, (Object[][])anotheralias)){
                    logln("Alias mechanism works for anotheralias");
                }else{
                    errln("Did not get the expected output for anotheralias");
                }
            
            }else{
                errln("Alias mechanism failed for anotheralias in TestAlias");
            }
            o = ((ICUListResourceBundle)uk).getObject("collations");
            Object o1 = rb.getObject("collations");
            if(o1 instanceof Object[][]&& o instanceof Object[][]){
                if(arrayEquals((Object[][])o, (Object[][])o1)){
                    logln("Alias mechanism works for CollationElements");
                }else{
                    errln("Did not get the expected output for collations");
                }
            
            }else{
                errln("Alias mechanism failed for collations in TestAlias");
            }
    
        }
                        
        Object o1 = rb.getObject("zoneTests");
        if(o1 instanceof Object[][]){
            if(arrayEquals(zoneTests, (Object[][])o1)){
                logln("Alias mechanism works for zoneTests");
            }else{
                errln("Did not get the expected output for zoneTests");
            }
            
        }else{
            errln("Alias mechanism failed for zoneTest in TestAlias");
        }
        o1 = rb.getObject("zoneStrings");
        if(o1 instanceof Object[]){
            if(Utility.arrayEquals(zoneStrings, (Object[])o1)){
                logln("Alias mechanism works for zoneStrings");
            }else{
                errln("Did not get the expected output for zoneStrings");
            }
            
        }else{
            errln("Alias mechanism failed for zoneStrings in TestAlias");
        }
        o1 = rb.getObject("testGetStringByIndexAliasing");
        if(o1 instanceof Object[]){
            if(Utility.arrayEquals(testGetStringByIndexAliasing, (Object[])o1)){
                logln("Alias mechanism works for testGetStringByIndexAliasing");
            }else{
                errln("Did not get the expected output for testGetStringByIndexAliasing");
            }
            
        }else{
            errln("Alias mechanism failed for testGetStringByIndexAliasing in TestAlias");
        }
        
        o1 = rb.getObject("testGetStringByKeyAliasing");
        if(o1 instanceof Object[][]){
            if(arrayEquals(testGetStringByKeyAliasing, (Object[][])o1)){
                logln("Alias mechanism works for testGetStringByKeyAliasing");
            }else{
                errln("Did not get the expected output for testGetStringByKeyAliasing");
            }
            
        }else{
            errln("Alias mechanism failed for testGetStringByKeyAliasing in TestAlias");
        }
        /* should not get an exception
        rb = ICULocaleData.getResourceBundle("com.ibm.icu.impl.data","LocaleElements","fr_BE");
        Object o = rb.getObject("SpelloutRules");
        if(o instanceof String){
            logln("Alias mechanism works");
        }else{
            errln("Alias mechanism failed for fr_BE SpelloutRules");
        }
        rb = ICULocaleData.getResourceBundle("com.ibm.icu.impl.data","LocaleElements","zh_TW");
        o = rb.getObject("collations");
        if(o instanceof Object[][]){
            Object[][] arr = (Object[][])o;
            if(((String)arr[0][0])== "default"){
                logln("Alias mechanism works");
            }else{
                errln("Alias mechanism failed for zh_TW collations");
            }
        }else{
            errln("Did not get the expected object for collations");
        }
        
        
    }
    */
    /*
    public void TestCircularAliases(){
        try{
            ResourceBundle rb = ICULocaleData.getResourceBundle("com.ibm.icu.dev.data","TestDataElements","testcircularalias");
            rb.getObject("aaa");
        }catch(java.util.MissingResourceException e){
            if(e.toString().indexOf("ircular")==-1){
                errln("Did not get the expected Exception for circular aliases");
            }
            return;
        }
        errln("Did not get the expected Exception for circular aliases");
    }*/
    /*
    public void TestGetObjectWithFallback(){
        ResourceBundle bundle = ICULocaleData.getResourceBundle("com.ibm.icu.impl.data","LocaleElements","te_IN");
        if(bundle instanceof ICUListResourceBundle){
            ICUListResourceBundle ilrb = (ICUListResourceBundle) bundle;
            String key = (String) ilrb.getObjectWithFallback("Keys/collation");
            if(!key.equals("COLLATION")){
                errln("Did not get the expected result from getObjectWithFallback method.");
            }
            String type = (String) ilrb.getObjectWithFallback("Types/collation/direct");
            if(!type.equals("DIRECT")){
                errln("Did not get the expected result form getObjectWithFallback method.");
            }
        }else{
            errln("Did not get the expected bundle.");
        }

        try{
            ResourceBundle bundle1 = ICULocaleData.getResourceBundle("com.ibm.icu.impl.data","LocaleElements","de__PHONEBOOK");
            if(bundle instanceof ICUListResourceBundle){
                ICUListResourceBundle ilrb = (ICUListResourceBundle) bundle1;
                String key = (String) ilrb.getObjectWithFallback("collations/collation/default");
                if(!key.equals("phonebook")){
                    errln("Did not get the expected result from getObjectWithFallback method.");
                }
    
            }else{
                errln("Did not get the expected bundle.");
            } 
            errln("Did not get the expected exception.");
        }catch(MissingResourceException ex){
            logln("got the expected exception");
        }

        
        ResourceBundle bundle1 = ICULocaleData.getResourceBundle("com.ibm.icu.impl.data","LocaleElements","fr_FR");
        if(bundle instanceof ICUListResourceBundle){
            ICUListResourceBundle ilrb = (ICUListResourceBundle) bundle1;
            String key = (String) ilrb.getObjectWithFallback("collations/default");
            if(!key.equals("standard")){
                errln("Did not get the expected result from getObjectWithFallback method.");
            }

        }else{
            errln("Did not get the expected bundle.");
        } 
        
        bundle1 = ICULocaleData.getResourceBundle("com.ibm.icu.impl.data","LocaleElements","es_ES");
        if(bundle instanceof ICUListResourceBundle){
            ICUListResourceBundle ilrb = (ICUListResourceBundle) bundle1;
            String key = (String) ilrb.getObjectWithFallback("collations/default");
            if(!key.equals("standard")){
                errln("Did not get the expected result from getObjectWithFallback method.");
            }
            String nkey = "collations/" + key;
            Object o = ilrb.getObjectWithFallback(nkey);
            if(o instanceof Object[][]){
                if(!((String) ((Object[][])o)[0][0]).equals("%%CollationBin")){
                    errln("Did not get the expected object for "+ nkey); 
                }else{
                    logln("Got the expected object for "+ nkey); 
                }
            }else{
                errln("Did not get the expected object for "+ nkey); 
            }
        }else{
            errln("Did not get the expected bundle.");
        }        
    }*/
    
}
