/*
**********************************************************************
* Copyright (c) 2002-2005, International Business Machines
* Corporation and others.  All Rights Reserved.
**********************************************************************
* Author: Alan Liu
* Created: November 5 2002
* Since: ICU 2.4
**********************************************************************
*/
package com.ibm.icu.impl;

import java.io.*;

import com.ibm.icu.lang.*;

/**
 * Wrapper for the pnames.icu binary data file.  This data file is
 * imported from icu4c.  It contains property and property value
 * aliases from the UCD files PropertyAliases.txt and
 * PropertyValueAliases.txt.  The file is built by the icu4c tool
 * genpname.  It must be built on an ASCII big-endian platform to be
 * usable in icu4j.
 *
 * This class performs two functions.
 *
 * (1) It can import the flat binary data into a tree of usable
 * objects.
 *
 * (2) It provides an API to access the tree of objects.
 *
 * Needless to say, this class is tightly coupled to the binary format
 * of icu4c's pnames.icu file.
 *
 * Each time a UPropertyAliases is constructed, the pnames.icu file is
 * read, parsed, and a data tree assembled.  Clients should create one
 * singleton instance and cache it.
 *
 * @author Alan Liu
 * @since ICU 2.4
 */
public final class UPropertyAliases implements ICUBinary.Authenticate {

    //----------------------------------------------------------------
    // Runtime data.  This is an unflattened representation of the
    // data in pnames.icu.

    /**
     * Map from property enum value to nameGroupPool[] index
     */
    private NonContiguousEnumToShort enumToName;

    /**
     * Map from property alias to property enum value
     */
    private NameToEnum nameToEnum;

    /**
     * Map from property enum value to valueMapArray[] index
     */
    private NonContiguousEnumToShort enumToValue;

    /**
     * Each entry represents a binary or enumerated property
     */
    private ValueMap valueMapArray[];

    /**
     * Pool of concatenated integer runs.  Each run contains one
     * or more entries.  The last entry of the run is negative.
     * A zero entry indicates "n/a" in the Property*Aliases.txt.
     * Each entry is a stringPool[] index.
     */
    private short nameGroupPool[];

    /**
     * Pool of strings.
     */
    private String stringPool[];

    //----------------------------------------------------------------
    // Constants

    /**
     * Debug flag (not really constant)
     */
    private static boolean DEBUG = ICUDebug.enabled("pnames");

    /**
     * File format that this class understands.
     * See icu4c/src/common/propname.h.
     */
    private static final byte DATA_FORMAT_ID[] = {'p', 'n', 'a', 'm'};

    /**
     * File version that this class understands.
     * See icu4c/src/common/propname.h.
     */
    private static final byte DATA_FORMAT_VERSION = 1;

    /**
     * Name of the datafile
     */
    private static final String DATA_FILE_NAME = ICUResourceBundle.ICU_BUNDLE+"/pnames.icu";

    /**
     * Buffer size of datafile.  The whole file is < 16k.
     */
    private static final int DATA_BUFFER_SIZE = 8192;

    //----------------------------------------------------------------
    // Constructor

    /**
     * Constructs a UPropertyAliases object.  The binary file
     * DATA_FILE_NAME is read from the jar/classpath and unflattened
     * into member variables of this object.
     */
    public UPropertyAliases() throws IOException {

        // Open the .icu file from the jar/classpath
        InputStream is = ICUData.getRequiredStream(DATA_FILE_NAME);
        BufferedInputStream b = new BufferedInputStream(is, DATA_BUFFER_SIZE);
        // Read and discard Unicode version...
       /* byte unicodeVersion[] = */ICUBinary.readHeader(b, DATA_FORMAT_ID, this);
        DataInputStream d = new DataInputStream(b);

        // Record the origin position of the file.  Keep enough around
        // to seek back to the start of the header.
        d.mark(256);

        short enumToName_offset = d.readShort();
        short nameToEnum_offset = d.readShort();
        short enumToValue_offset = d.readShort();
        short total_size = d.readShort();
        short valueMap_offset = d.readShort();
        short valueMap_count = d.readShort();
        short nameGroupPool_offset = d.readShort();
        short nameGroupPool_count = d.readShort();
        short stringPool_offset = d.readShort();
        short stringPool_count = d.readShort();

        if (DEBUG) {
            System.out.println(
               "enumToName_offset=" + enumToName_offset + "\n" +
               "nameToEnum_offset=" + nameToEnum_offset + "\n" +
               "enumToValue_offset=" + enumToValue_offset + "\n" +
               "total_size=" + total_size + "\n" +
               "valueMap_offset=" + valueMap_offset + "\n" +
               "valueMap_count=" + valueMap_count + "\n" +
               "nameGroupPool_offset=" + nameGroupPool_offset + "\n" +
               "nameGroupPool_count=" + nameGroupPool_count + "\n" +
               "stringPool_offset=" + stringPool_offset + "\n" +
               "stringPool_count=" + stringPool_count);
        }

        // Read it all (less than 32k).  Seeking around (using
        // mark/reset/skipBytes) doesn't work directly on the file,
        // but it works fine if we read everything into a byte[] array
        // first.
        byte raw[] = new byte[total_size];
        d.reset();
        d.read(raw);
        d.close();

        Builder builder = new Builder(raw);

        stringPool = builder.readStringPool(stringPool_offset,
                                            stringPool_count);

        nameGroupPool = builder.readNameGroupPool(nameGroupPool_offset,
                                                  nameGroupPool_count);

        builder.setupValueMap_map(valueMap_offset, valueMap_count);

        // Some of the following data structures have to be set up
        // here, _not_ in Builder.  That's because they are instances
        // of non-static inner classes, and they contain implicit
        // references to this.

        builder.seek(enumToName_offset);
        enumToName = new NonContiguousEnumToShort(builder);
        builder.nameGroupOffsetToIndex(enumToName.offsetArray);

        builder.seek(nameToEnum_offset);
        nameToEnum = new NameToEnum(builder);

        builder.seek(enumToValue_offset);
        enumToValue = new NonContiguousEnumToShort(builder);
        builder.valueMapOffsetToIndex(enumToValue.offsetArray);

        valueMapArray = new ValueMap[valueMap_count];
        for (int i=0; i<valueMap_count; ++i) {
            // Must seek to the start of each entry.
            builder.seek(builder.valueMap_map[i]);
            valueMapArray[i] = new ValueMap(builder);
        }

        builder.close();
    }

    //----------------------------------------------------------------
    // Public API

    /**
     * Return a property name given a property enum.  Multiple
     * names may be available for each property; the nameChoice
     * selects among them.
     */
    public String getPropertyName(int property,
                                  int nameChoice) {
        short nameGroupIndex = enumToName.getShort(property);
        return chooseNameInGroup(nameGroupIndex, nameChoice);
    }

    /**
     * Return a property enum given one of its property names.
     */
    public int getPropertyEnum(String propertyAlias) {
        return nameToEnum.getEnum(propertyAlias);
    }

    /**
     * Return a value name given a property enum and a value enum.
     * Multiple names may be available for each value; the nameChoice
     * selects among them.
     */
    public String getPropertyValueName(int property,
                                       int value,
                                       int nameChoice) {
        ValueMap vm = getValueMap(property);
        short nameGroupIndex = vm.enumToName.getShort(value);
        return chooseNameInGroup(nameGroupIndex, nameChoice);
    }

    /**
     * Return a value enum given one of its value names and the
     * corresponding property alias.
     */
    public int getPropertyValueEnum(int property,
                                    String valueAlias) {
        ValueMap vm = getValueMap(property);
        return vm.nameToEnum.getEnum(valueAlias);
    }

    //----------------------------------------------------------------
    // Data structures

    /**
     * A map for the legal values of a binary or enumerated properties.
     */
    private class ValueMap {

        /**
         * Maps value enum to index into the nameGroupPool[]
         */
        EnumToShort enumToName; // polymorphic

        /**
         * Maps value name to value enum.
         */
        NameToEnum nameToEnum;

        ValueMap(Builder b) throws IOException {
            short enumToName_offset = b.readShort();
            short ncEnumToName_offset = b.readShort();
            short nameToEnum_offset = b.readShort();
            if (enumToName_offset != 0) {
                b.seek(enumToName_offset);
                ContiguousEnumToShort x = new ContiguousEnumToShort(b);
                b.nameGroupOffsetToIndex(x.offsetArray);
                enumToName = x;
            } else {
                b.seek(ncEnumToName_offset);
                NonContiguousEnumToShort x = new NonContiguousEnumToShort(b);
                b.nameGroupOffsetToIndex(x.offsetArray);
                enumToName = x;
            }
            b.seek(nameToEnum_offset);
            nameToEnum = new NameToEnum(b);
        }
    }

    /**
     * Abstract map from enum values to integers.
     */
    private interface EnumToShort {
        short getShort(int enumProbe);
    }

    /**
     * Generic map from enum values to offsets.  Enum values are
     * contiguous.
     */
    private static class ContiguousEnumToShort implements EnumToShort {
        int enumStart;
        int enumLimit;
        short offsetArray[];

        public short getShort(int enumProbe) {
            if (enumProbe < enumStart || enumProbe >= enumLimit) {
                throw new IllegalArgumentException("Invalid enum. enumStart = " +enumStart +
                                                   " enumLimit = " + enumLimit +
                                                   " enumProbe = " + enumProbe );
            }
            return offsetArray[enumProbe - enumStart];
        }

        ContiguousEnumToShort(ICUBinaryStream s) throws IOException  {
            enumStart = s.readInt();
            enumLimit = s.readInt();
            int count = enumLimit - enumStart;
            offsetArray = new short[count];
            for (int i=0; i<count; ++i) {
                offsetArray[i] = s.readShort();
            }
        }
    }

    /**
     * Generic map from enum values to offsets.  Enum values need not
     * be contiguous.
     */
    private static class NonContiguousEnumToShort implements EnumToShort {
        int enumArray[];
        short offsetArray[];

        public short getShort(int enumProbe) {
            for (int i=0; i<enumArray.length; ++i) {
                if (enumArray[i] < enumProbe) continue;
                if (enumArray[i] > enumProbe) break;
                return offsetArray[i];
            }
            throw new IllegalArgumentException("Invalid enum");
        }

        NonContiguousEnumToShort(ICUBinaryStream s) throws IOException  {
            int i;
            int count = s.readInt();
            enumArray = new int[count];
            offsetArray = new short[count];
            for (i=0; i<count; ++i) {
                enumArray[i] = s.readInt();
            }
            for (i=0; i<count; ++i) {
                offsetArray[i] = s.readShort();
            }
        }
    }

    /**
     * Map from names to enum values.
     */
    private class NameToEnum {
        int enumArray[];
        short nameArray[];

        int getEnum(String nameProbe) {
            for (int i=0; i<nameArray.length; ++i) {
                int c = UPropertyAliases.compare(nameProbe,
                                                 stringPool[nameArray[i]]);
                if (c > 0) continue;
                if (c < 0) break;
                return enumArray[i];
            }
            throw new IllegalArgumentException("Invalid name: " + nameProbe);
        }

        NameToEnum(Builder b) throws IOException {
            int i;
            int count = b.readInt();
            enumArray = new int[count];
            nameArray = new short[count];
            for (i=0; i<count; ++i) {
                enumArray[i] = b.readInt();
            }
            for (i=0; i<count; ++i) {
                nameArray[i] = b.stringOffsetToIndex(b.readShort());
            }
        }
    }

    //----------------------------------------------------------------
    // Runtime implementation

    /**
     * Compare two property names, returning <0, 0, or >0.  The
     * comparison is that described as "loose" matching in the
     * Property*Aliases.txt files.
     */
    public static int compare(String stra, String strb) {
        // Note: This implementation is a literal copy of
        // uprv_comparePropertyNames.  It can probably be improved.
        int istra=0, istrb=0, rc;
        int cstra=0, cstrb=0;
        for (;;) {
            /* Ignore delimiters '-', '_', and ASCII White_Space */
            while (istra<stra.length()) {
                cstra = stra.charAt(istra);
                switch (cstra) {
                case '-':  case '_':  case ' ':  case '\t':
                case '\n': case 0xb/*\v*/: case '\f': case '\r':
                    ++istra;
                    continue;
                }
                break;
            }

            while (istrb<strb.length()) {
                cstrb = strb.charAt(istrb);
                switch (cstrb) {
                case '-':  case '_':  case ' ':  case '\t':
                case '\n': case 0xb/*\v*/: case '\f': case '\r':
                    ++istrb;
                    continue;
                }
                break;
            }

            /* If we reach the ends of both strings then they match */
            boolean endstra = istra==stra.length();
            boolean endstrb = istrb==strb.length();
            if (endstra) {
                if (endstrb) return 0;
                cstra = 0;
            } else if (endstrb) {
                cstrb = 0;
            }

            rc = UCharacter.toLowerCase(cstra) - UCharacter.toLowerCase(cstrb);
            if (rc != 0) {
                return rc;
            }

            ++istra;
            ++istrb;
        }
    }

    /**
     * Given an index to a run within the nameGroupPool[], and a
     * nameChoice (0,1,...), select the nameChoice-th entry of the run.
     */
    private String chooseNameInGroup(short nameGroupIndex, int nameChoice) {
        if (nameChoice < 0) {
            throw new IllegalArgumentException("Invalid name choice");
        }
        while (nameChoice-- > 0) {
            if (nameGroupPool[nameGroupIndex++] < 0) {
                throw new IllegalArgumentException("Invalid name choice");
            }
        }
        short a = nameGroupPool[nameGroupIndex];
        return stringPool[(a < 0) ? -a : a];
    }

    /**
     * Return the valueMap[] entry for a given property.
     */
    private ValueMap getValueMap(int property) {
        int valueMapIndex = enumToValue.getShort(property);
        return valueMapArray[valueMapIndex];
    }

    //----------------------------------------------------------------
    // ICUBinary API

    /**
     * Return true if the given data version can be used.
     */
    public boolean isDataVersionAcceptable(byte version[])   {
        return version[0] == DATA_FORMAT_VERSION;
    }

    //----------------------------------------------------------------
    // Builder

    /**
     * A specialized ICUBinaryStream that can map between offsets and
     * index values into various arrays (stringPool, nameGroupPool,
     * and valueMap).  It also knows how to read various structures.
     */
    static class Builder extends ICUBinaryStream {

        // map[i] = offset of object i.  We need maps for all of our
        // arrays.  The arrays are indexed by offset in the raw binary
        // file; we need to translate that to index.

        private short stringPool_map[];

        private short valueMap_map[];

        private short nameGroup_map[];

        public Builder(byte raw[]) {
            super(raw);
        }

        /**
         * The valueMap_map[] must be setup in advance.  This method
         * does that.
         */
        public void setupValueMap_map(short offset, short count) {
            valueMap_map = new short[count];
            for (int i=0; i<count; ++i) {
                // Start of each entry.  Each entry is 6 bytes long.
                valueMap_map[i] = (short) (offset + i * 6);
            }
        }

        /**
         * Read stringPool[].  Build up translation table from offsets
         * to string indices (stringPool_map[]).
         */
        public String[] readStringPool(short offset, short count)
            throws IOException {
            seek(offset);
            // Allocate one more stringPool entry than needed.  Use this
            // to store a "no string" entry in the pool, at index 0.  This
            // maps to offset 0, so let stringPool_map[0] = 0.
            String stringPool[] = new String[count + 1];
            stringPool_map = new short[count + 1];
            short pos = offset;
            StringBuffer buf = new StringBuffer();
            stringPool_map[0] = 0;
            for (int i=1; i<=count; ++i) {
                buf.setLength(0);
                for (;;) {
                    // This works because the name is invariant-ASCII
                    char c = (char) readUnsignedByte();
                    if (c == 0) break;
                    buf.append(c);
                }
                stringPool_map[i] = pos;
                stringPool[i] = buf.toString();
                pos += stringPool[i].length() + 1;
            }
            if (DEBUG) {
                System.out.println("read stringPool x " + count +
                                   ": " + stringPool[1] + ", " +
                                   stringPool[2] + ", " +
                                   stringPool[3] + ",...");
            }
            return stringPool;
        }

        /**
         * Read the nameGroupPool[], and build up the offset->index
         * map (nameGroupPool_map[]).
         */
        public short[] readNameGroupPool(short offset, short count)
            throws IOException {
            // Read nameGroupPool[].  This contains offsets from start of
            // header.  We translate these into indices into stringPool[]
            // on the fly.  The offset 0, which indicates "no entry", we
            // translate into index 0, which contains a null String
            // pointer.
            seek(offset);
            short pos = offset;
            short nameGroupPool[] = new short[count];
            nameGroup_map = new short[count];
            for (int i=0; i<count; ++i) {
                nameGroup_map[i] = pos;
                nameGroupPool[i] = stringOffsetToIndex(readShort());
                pos += 2;
            }
            if (DEBUG) {
                System.out.println("read nameGroupPool x " + count +
                                   ": " + nameGroupPool[0] + ", " +
                                   nameGroupPool[1] + ", " +
                                   nameGroupPool[2] + ",...");
            }
            return nameGroupPool;
        }

        /**
         * Convert an offset into the string pool into a stringPool[]
         * index.
         */
        private short stringOffsetToIndex(short offset) {
            int probe = offset;
            if (probe < 0) probe = -probe;
            for (int i=0; i<stringPool_map.length; ++i) {
                if (stringPool_map[i] == probe) {
                    return (short) ((offset < 0) ? -i : i);
                }
            }
            throw new InternalError("Can't map string pool offset " + offset +
                                       " to index");
        }

        /**
         * Convert an array of offsets into the string pool into an
         * array of stringPool[] indices.  MODIFIES THE ARRAY IN
         * PLACE.
         */
        ///CLOVER:OFF
        private void stringOffsetToIndex(short array[]) {
            for (int i=0; i<array.length; ++i) {
                array[i] = stringOffsetToIndex(array[i]);
            }
        }
        ///CLOVER:ON

        /**
         * Convert an offset into the value map into a valueMap[]
         * index.
         */
        private short valueMapOffsetToIndex(short offset) {
            for (short i=0; i<valueMap_map.length; ++i) {
                if (valueMap_map[i] == offset) {
                    return i;
                }
            }
            throw new InternalError("Can't map value map offset " + offset +
                                       " to index");
        }

        /**
         * Convert an array of offsets into the value map array into
         * an array of valueMap[] indices.  MODIFIES THE ARRAY IN
         * PLACE.
         */
        private void valueMapOffsetToIndex(short array[]) {
            for (int i=0; i<array.length; ++i) {
                array[i] = valueMapOffsetToIndex(array[i]);
            }
        }

        /**
         * Convert an offset into the name group pool into a
         * nameGroupPool[] index.
         */
        private short nameGroupOffsetToIndex(short offset) {
            for (short i=0; i<nameGroup_map.length; ++i) {
                if (nameGroup_map[i] == offset) {
                    return i;
                }
            }
            throw new RuntimeException("Can't map name group offset " + offset +
                                       " to index");
        }

        /**
         * Convert an array of offsets into the name group pool into an
         * array of nameGroupPool[] indices.  MODIFIES THE ARRAY IN
         * PLACE.
         */
        private void nameGroupOffsetToIndex(short array[]) {
            for (int i=0; i<array.length; ++i) {
                array[i] = nameGroupOffsetToIndex(array[i]);
            }
        }
    }
}
