/*
 ******************************************************************************
 * Copyright (C) 2004-2005, International Business Machines Corporation and   *
 * others. All Rights Reserved.                                               *
 ******************************************************************************
 */
package com.ibm.icu.impl;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import com.ibm.icu.util.StringTokenizer;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.UResourceTypeMismatchException;
/**
 * @author ram
 */
public class ICUResourceBundleImpl extends ICUResourceBundle {
    //protected byte[] version;
    private byte[] rawData;
    private long rootResource;
    private String localeID;
    private String baseName;
    private ULocale ulocale;

    /**
     * 
     * @param baseName
     * @param localeID
     * @param root
     * @return the new bundle
     */
    public static ICUResourceBundle createBundle(String baseName,
            String localeID, ClassLoader root) {

        ICUResourceBundleReader reader = ICUResourceBundleReader.getReader(
                baseName, localeID, root);

        // could not open the .res file so return null
        if (reader == null) {
            return null;
        }

        byte[] rawData = reader.getData();
        long rootResource = (UNSIGNED_INT_MASK) & getInt(rawData, 0);
        ICUResourceBundleImpl bundle = new ICUResourceBundleImpl(rawData,
                baseName, localeID, rootResource);
        return bundle.getBundle();
    }

    protected String getLocaleID() {
        return localeID;
    }

    protected String getBaseName() {
        return baseName;
    }

    public ULocale getULocale() {
        return ulocale;
    }

    public UResourceBundle getParent() {
        return (UResourceBundle) parent;
    }

    protected void setParent(ResourceBundle parent) {
        this.parent = parent;
    }

    private ICUResourceBundle getBundle() {
        int type = RES_GET_TYPE(rootResource);
        if (type == TABLE) {
            ResourceTable table = new ResourceTable(null, rootResource, "", true);
            if(table.size==1){
                ICUResourceBundle b = table.handleGet(0, table);
                String itemKey = b.getKey();
                
                // %%ALIAS is such a hack!
                if (itemKey.equals("%%ALIAS")) {
                    String locale = b.getString();
                    ICUResourceBundle actual = (ICUResourceBundle) UResourceBundle.getBundleInstance(baseName, locale);
                    return (ResourceTable) actual;
                }else{
                    return table;
                }
            }else {
                return table;
            }
        } else if (type == TABLE32) {

            // genrb does not generate Table32 with %%ALIAS
            return new ResourceTable32(null, rootResource, "", true);
        } else {
            throw new InternalError("Invalid format error");
        }
    }
    private ICUResourceBundleImpl(byte[] rawData, String baseName,
            String localeID, long rootResource) {
        this.rawData = rawData;
        this.rootResource = rootResource;
        this.baseName = baseName;
        this.localeID = localeID;
        this.ulocale = new ULocale(localeID);
    }
    private static final int RES_GET_TYPE(long res) {
        return (int) ((res) >> 28L);
    }
    private static final int RES_GET_OFFSET(long res) {
        return (int) ((res & 0x0fffffff) * 4);
    }
    /* get signed and unsigned integer values directly from the Resource handle */
    private static final int RES_GET_INT(long res) {
        return (((int) ((res) << 4L)) >> 4L);
    }
    private static final long RES_GET_UINT(long res) {
        long t = ((res) & 0x0fffffffL);
        return t;
    }
    private static final StringBuffer RES_GET_KEY(byte[] rawData,
            int keyOffset) {
        char ch = 0xFFFF; //sentinel
        StringBuffer key = new StringBuffer();
        while ((ch = (char) rawData[keyOffset]) != 0) {
            key.append(ch);
            keyOffset++;
        }
        return key;
    }
    private static final int getIntOffset(int offset) {
        return (offset * 4);
    }
    private static final int getCharOffset(int offset) {
        return (offset * 2);
    }
    private final ICUResourceBundle createBundleObject(String key,
            long resource, String resPath, HashMap table, ICUResourceBundle requested) {
        //if (resource != RES_BOGUS) {
        switch (RES_GET_TYPE(resource)) {
            case STRING : {
                return new ResourceString(key, resPath, resource);
            }
            case BINARY : {
                return new ResourceBinary(key, resPath, resource);
            }
            case ALIAS : {
                return findResource(key, resource, table, requested);
            }
            case INT : {
                return new ResourceInt(key, resPath, resource);
            }
            case INT_VECTOR : {
                return new ResourceIntVector(key, resPath, resource);
            }
            case ARRAY : {
                return new ResourceArray(key, resPath, resource);
            }
            case TABLE32 : {
                return new ResourceTable32(key, resPath, resource);
            }
            case TABLE : {
                return new ResourceTable(key, resPath, resource);
            }
            default :
                throw new InternalError("The resource type is unknown");
        }
        //}
        //return null;
    }
    private int findKey(int size, int currentOffset, Resource res, String target) {
        int mid = 0, start = 0, limit = size, rc;
        int lastMid = -1;
        //int myCharOffset = 0, keyOffset = 0;
        for (;;) {
            mid = ((start + limit) / 2);
            if (lastMid == mid) { /* Have we moved? */
                break; /* We haven't moved, and it wasn't found. */
            }
            lastMid = mid;
            String comp = res.getKey(currentOffset, mid);
            rc = target.compareTo(comp);
            if (rc < 0) {
                limit = mid;
            } else if (rc > 0) {
                start = mid;
            } else {
                return mid;
            }
        }
        return -1;
    }
    private interface Resource {
        public String getKey(int currentOfset, int index);
    }
    private class ResourceTable extends ICUResourceBundle implements Resource {

        protected ICUResourceBundle handleGet(String key, ICUResourceBundle requested) {
            return handleGet(key, null, requested);
        }
        protected ICUResourceBundle handleGet(String key, HashMap table, ICUResourceBundle requested) {
            if(size<=0){
                return null;
            }
            int offset = RES_GET_OFFSET(resource);
            // offset+0 contains number of entries
            // offset+1 contains the keyOffset  
            int currentOffset = (offset) + getCharOffset(1);
            //int keyOffset = rawData.getChar(currentOffset);
            /* do a binary search for the key */
            int foundOffset = findKey(size, currentOffset, this, key);
            if (foundOffset == -1) {
                //throw new MissingResourceException(ICUResourceBundleReader.getFullName(baseName, localeID),
                //                                    localeID,
                //                                    key);
                return null;
            }
            currentOffset += getCharOffset(size + (~size & 1))
                    + getIntOffset(foundOffset);
            long resource = (UNSIGNED_INT_MASK) & ICUResourceBundleImpl.getInt(rawData, currentOffset);
            String path = (isTopLevel == true) ? key : resPath + "/" + key;
            return createBundleObject(key, resource, path, table, requested);
        }
        protected ICUResourceBundle handleGet(int index, ICUResourceBundle requested) {
            return handleGet(index, null, requested);
        }
        public String getKey(int currentOffset, int index) {
            int charOffset = currentOffset + getCharOffset(index);
            int keyOffset = getChar(rawData,charOffset);
            return RES_GET_KEY(rawData, keyOffset).toString();
        }
        protected ICUResourceBundle handleGet(int index, HashMap table, ICUResourceBundle requested) {
            if (index > size) {
                throw new IndexOutOfBoundsException();
            }
            int offset = RES_GET_OFFSET(resource);
            // offset+0 contains number of entries
            // offset+1 contains the keyOffset  
            int currentOffset = (offset) + getCharOffset(1);
            String itemKey = getKey(currentOffset, index);
            currentOffset += getCharOffset(size + (~size & 1))
                    + getIntOffset(index);
            long resource = (UNSIGNED_INT_MASK) & ICUResourceBundleImpl.getInt(rawData,currentOffset);
            String path = (isTopLevel == true)
                    ? Integer.toString(index)
                    : resPath + "/" + index;
            return createBundleObject(itemKey, resource, path, table, requested);
        }
        private int countItems() {
            int offset = RES_GET_OFFSET(resource);
            int value = getChar(rawData,offset);
            return value;
        }
        private ResourceTable(String key, String resPath, long resource) {
            this(key, resource, resPath, false);
        }
        private ResourceTable(String key, long resource, String resPath,
                boolean isTopLevel) {
            this.key = key;
            this.resource = resource;
            this.isTopLevel = isTopLevel;
            this.size = countItems();
            this.resPath = resPath;
        }
        protected String getLocaleID() {
            return localeID;
        }
        protected String getBaseName() {
            return baseName;
        }

        public ULocale getULocale() {
            return ulocale;
        }
        public UResourceBundle getParent() {
            return ICUResourceBundleImpl.this.getParent();
        }
        protected void setParent(ResourceBundle parent) {
            ICUResourceBundleImpl.this.setParent(parent);
        }
    }
    private class ResourceTable32 extends ICUResourceBundle implements Resource {

        protected ICUResourceBundle handleGet(String key, ICUResourceBundle requested) {
            if(size<=0){
                return null;
            }
            return handleGet(key, null, requested);
        }
        protected ICUResourceBundle handleGet(String key, HashMap table, ICUResourceBundle requested) {
            int offset = RES_GET_OFFSET(resource);
            // offset+0 contains number of entries
            // offset+1 contains the keyOffset  
            int currentOffset = (offset) + getIntOffset(1);
            //int keyOffset = rawData.getChar(currentOffset);
            /* do a binary search for the key */
            int foundOffset = findKey(size, currentOffset, this, key);
            if (foundOffset == -1) {
                throw new MissingResourceException(
                        "Could not find resource ",
                        ICUResourceBundleReader.getFullName(baseName, localeID),
                        key);
            }
            currentOffset += getIntOffset(size) + getIntOffset(foundOffset);
            long resource = (UNSIGNED_INT_MASK) & ICUResourceBundleImpl.getInt(rawData,currentOffset);
            String path = (isTopLevel == true) ? key : resPath + "/" + key;
            return createBundleObject(key, resource, path, table, requested);
        }
        protected ICUResourceBundle handleGet(int index, ICUResourceBundle requested) {
            return handleGet(index, null, requested);
        }
        public String getKey(int currentOffset, int index) {
            int charOffset = currentOffset + getIntOffset(index);
            int keyOffset = ICUResourceBundleImpl.getInt(rawData,charOffset);
            return RES_GET_KEY(rawData, keyOffset).toString();
        }
        protected ICUResourceBundle handleGet(int index, HashMap table, ICUResourceBundle requested) {
            if (index > size) {
                throw new IndexOutOfBoundsException();
            }
            int offset = RES_GET_OFFSET(resource);
            // offset+0 contains number of entries
            // offset+1 contains the keyOffset  
            int currentOffset = (offset) + getIntOffset(1)
                    + getIntOffset(index);
            String itemKey = getKey(currentOffset, 0);
            currentOffset += getIntOffset(size);
            long resource = (UNSIGNED_INT_MASK) & ICUResourceBundleImpl.getInt(rawData,currentOffset);
            String path = (isTopLevel == true)
                    ? Integer.toString(index)
                    : resPath + "/" + index;
            return createBundleObject(itemKey, resource, path, table, requested);
        }
        private int countItems() {
            int offset = RES_GET_OFFSET(resource);
            int value = ICUResourceBundleImpl.getInt(rawData, offset);
            return value;
        }
        private ResourceTable32(String key, long resource, String resPath,
                boolean isTopLevel) {
            this.resource = resource;
            this.key = key;
            this.type = TABLE;//Mask the table32's real type
            this.isTopLevel = isTopLevel;
            this.size = countItems();
            this.resPath = resPath;
        }
        private ResourceTable32(String key, String resPath, long resource) {
            this(key, resource, resPath, false);
        }

        protected String getLocaleID() {
            return localeID;
        }
        protected String getBaseName() {
            return baseName;
        }

        public ULocale getULocale() {
            return ulocale;
        }
        public UResourceBundle getParent() {
            return ICUResourceBundleImpl.this.getParent();
        }
        protected void setParent(ResourceBundle parent) {
            ICUResourceBundleImpl.this.setParent(parent);
        }

    }
    private class ResourceString extends ICUResourceBundle {
        private String value;
        public String getString() {
            return value;
        }
        private ResourceString(String key, String resPath, long resource) {
            value = getStringValue(resource);
            this.key = key;
            this.resource = resource;
            this.type = RES_GET_TYPE(resource);
            this.resPath = resPath;
        }
        protected String getLocaleID() {
            return localeID;
        }
        protected String getBaseName() {
            return baseName;
        }

        public ULocale getULocale() {
            return ulocale;
        }
        public UResourceBundle getParent() {
            return ICUResourceBundleImpl.this.getParent();
        }
    }
    private class ResourceInt extends ICUResourceBundle {
        public int getInt() {
            return RES_GET_INT(resource);
        }
        public int getUInt() {
            long ret = RES_GET_UINT(resource);
            return (int) ret;
        }
        private ResourceInt(String key, String resPath, long resource) {
            this.key = key;
            this.resource = resource;
            this.type = RES_GET_TYPE(resource);
            this.resPath = resPath;
        }
        protected String getLocaleID() {
            return localeID;
        }
        protected String getBaseName() {
            return baseName;
        }

        public ULocale getULocale() {
            return ulocale;
        }
        public UResourceBundle getParent() {
            return ICUResourceBundleImpl.this.getParent();
        }
    }
    private class ResourceArray extends ICUResourceBundle {
        protected String[] handleGetStringArray() {
            String[] strings = new String[size];
            ICUResourceBundleIterator iter = getIterator();
            int i = 0;
            while (iter.hasNext()) {
                strings[i++] = iter.next().getString();
            }
            return strings;
        }
        /**
         * @internal ICU 3.0
         */
        public String[] getStringArray() {
            return handleGetStringArray();
        }
        protected ICUResourceBundle handleGet(String index, ICUResourceBundle requested) {
            return handleGet(index, null, requested);
        }
        protected ICUResourceBundle handleGet(String index, HashMap table, ICUResourceBundle requested) {
            int val = getIndex(index);
            if (val > -1) {
                return handleGet(val, table, requested);
            }
            throw new UResourceTypeMismatchException("Could not get the correct value for index: "+ index);
        }
        protected ICUResourceBundle handleGet(int index, ICUResourceBundle requested) {
            return handleGet(index, null, requested);
        }
        protected ICUResourceBundle handleGet(int index, HashMap table, ICUResourceBundle requested) {
            if (index > size) {
                throw new IndexOutOfBoundsException();
            }
            int offset = RES_GET_OFFSET(resource);
            int itemOffset = offset + getIntOffset(index + 1);
            long itemResource = (UNSIGNED_INT_MASK) & ICUResourceBundleImpl.getInt(rawData,itemOffset);
            String path = (isTopLevel == true) ? Integer.toString(index) : resPath + "/" + index;
            return createBundleObject(null, itemResource, path, table, requested);
        }
        private int countItems() {
            int offset = RES_GET_OFFSET(resource);
            int value = ICUResourceBundleImpl.getInt(rawData,offset);
            return value;
        }
        private ResourceArray(String key, String resPath, long resource) {
            this.resource = resource;
            this.key = key;
            this.type = RES_GET_TYPE(resource);
            this.size = countItems();
            this.resPath = resPath;
        }
        protected String getLocaleID() {
            return localeID;
        }
        protected String getBaseName() {
            return baseName;
        }

        public ULocale getULocale() {
            return ulocale;
        }
        public UResourceBundle getParent() {
            return ICUResourceBundleImpl.this.getParent();
        }
    }
    private static char makeChar(byte b1, byte b0) {
        return (char)((b1 << 8) | (b0 & 0xff));
    }
    private static char getChar(byte[]data, int offset){
        return makeChar(data[offset], data[offset+1]);
    }
    private static int makeInt(byte b3, byte b2, byte b1, byte b0) {
        return (int)((((b3 & 0xff) << 24) |
                  ((b2 & 0xff) << 16) |
                  ((b1 & 0xff) <<  8) |
                  ((b0 & 0xff) <<  0)));
    }
    
    private static int getInt(byte[] data, int offset){
        assert offset < data.length;
        return makeInt(data[offset], data[offset+1], 
                       data[offset+2], data[offset+3]);
    }
    
    private class ResourceBinary extends ICUResourceBundle {
        private byte[] value;
        public ByteBuffer getBinary() {
            return ByteBuffer.wrap(value);
        }
        private byte[] getValue() {
            int offset = RES_GET_OFFSET(resource);
            int length = ICUResourceBundleImpl.getInt(rawData,offset);
            int byteOffset = offset + getIntOffset(1);
            byte[] dst = new byte[length];
            assert byteOffset+length < rawData.length;
            System.arraycopy(rawData, byteOffset, dst, 0, length);
            return dst;
        }
        public ResourceBinary(String key, String resPath, long resource) {
            this.resource = resource;
            this.key = key;
            this.type = RES_GET_TYPE(resource);
            this.resPath = resPath;
            value = getValue();
        }
        protected String getLocaleID() {
            return localeID;
        }
        protected String getBaseName() {
            return baseName;
        }

        public ULocale getULocale() {
            return ulocale;
        }
        public UResourceBundle getParent() {
            return ICUResourceBundleImpl.this.getParent();
        }
    }
    private class ResourceIntVector extends ICUResourceBundle {
        private int[] value;
        public int[] getIntVector() {
            return value;
        }
        private int[] getValue() {
            int offset = RES_GET_OFFSET(resource);
            int length = ICUResourceBundleImpl.getInt(rawData,offset);
            int intOffset = offset + getIntOffset(1);
            int[] val = new int[length];
            int byteLength = getIntOffset(length);
            
            assert (intOffset+byteLength)<rawData.length;
            
            for(int i=0; i<length;i++){
                val[i]=ICUResourceBundleImpl.getInt(rawData, intOffset+getIntOffset(i));
            }
            return val;
        }
        public ResourceIntVector(String key, String resPath, long resource) {
            this.key = key;
            this.resource = resource;
            this.size = 1;
            this.type = RES_GET_TYPE(resource);
            this.resPath = resPath;
            value = getValue();
        }
        protected String getLocaleID() {
            return localeID;
        }
        protected String getBaseName() {
            return baseName;
        }

        public ULocale getULocale() {
            return ulocale;
        }
        public UResourceBundle getParent() {
            return ICUResourceBundleImpl.this.getParent();
        }
    }
    private String getStringValue(long resource) {
        int offset = RES_GET_OFFSET(resource);
        int length = getInt(rawData,offset);
        int stringOffset = offset + getIntOffset(1);
        char[] dst = new char[length];
        assert (stringOffset+getCharOffset(length)) < rawData.length;
        for(int i=0; i<length; i++){
            dst[i]=getChar(rawData, stringOffset+getCharOffset(i));
        }
        return new String(dst);
    }
    private static final char RES_PATH_SEP_CHAR = '/';
    private static final String ICUDATA = "ICUDATA";
    private static final String LOCALE = "LOCALE";
    
    private static final int getIndex(String s) {
        if (s.length() >= 1) {
            return Integer.valueOf(s).intValue();
        }
        return -1;
    }
    private ICUResourceBundle findResource(String key, long resource,
            HashMap table, ICUResourceBundle requested) {
        String locale = null, keyPath = null;
        String bundleName;
        String resPath = getStringValue(resource);
        if (table == null) {
            table = new HashMap();
        }
        if (table.get(resPath) != null) {
            throw new IllegalArgumentException(
                    "Circular references in the resource bundles");
        }
        table.put(resPath, "");
        if (resPath.indexOf(RES_PATH_SEP_CHAR) == 0) {
            int i = resPath.indexOf(RES_PATH_SEP_CHAR, 1);
            int j = resPath.indexOf(RES_PATH_SEP_CHAR, i + 1);
            bundleName = resPath.substring(1, i);
            locale = resPath.substring(i + 1);
            if (j != -1) {
                locale = resPath.substring(i + 1, j);
                keyPath = resPath.substring(j + 1, resPath.length());
            }
            //there is a path included
            if (bundleName.equals(ICUDATA)) {
                bundleName = ICU_BASE_NAME;
            }
        } else {
            //no path start with locale
            int i = resPath.indexOf(RES_PATH_SEP_CHAR);
            keyPath = resPath.substring(i + 1);
            if (i != -1) {
                locale = resPath.substring(0, i);
            } else {
                locale = keyPath;
                keyPath = null;//keyPath.substring(i, keyPath.length());
            }
            bundleName = baseName;
        }
        ICUResourceBundle bundle = null;
        if(bundleName.equals(LOCALE)){
            bundleName = baseName;
            bundle = requested;
            keyPath = resPath.substring(LOCALE.length() + 2/* prepending and appending / */, resPath.length());
            locale = requested.getLocaleID();
        }else if (locale == null) {
            bundle = (ICUResourceBundle) getBundleInstance(bundleName, "",
                    ICU_DATA_CLASS_LOADER, false);
        } else {
            bundle = (ICUResourceBundle) getBundleInstance(bundleName, locale,
                    ICU_DATA_CLASS_LOADER, false);
        }
        ICUResourceBundle sub = null;
        if (keyPath != null) {
            StringTokenizer st = new StringTokenizer(keyPath, "/");
            ICUResourceBundle current = bundle;
            while (st.hasMoreTokens()) {
                String subKey = st.nextToken();
                sub = current.getImpl(subKey, table, requested);
                if (sub == null) {
                    break;
                }
                current = sub;
            }
        } else {
            // if the sub resource is not found
            // try fetching the sub resource with
            // the key of this alias resource
            sub = bundle.get(key);
        }
        if (sub == null) {
            throw new MissingResourceException(localeID, baseName, key);
        }
        sub.resPath = resPath;
        return sub;
    }
}
