/*
**********************************************************************
* Copyright (c) 2002, 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 = "data/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 = getClass().getResourceAsStream(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 RuntimeException("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.
         */
        private void stringOffsetToIndex(short array[]) {
            for (int i=0; i<array.length; ++i) {
                array[i] = stringOffsetToIndex(array[i]);
            }
        }

        /**
         * 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 RuntimeException("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]);
            }
        }
    }
}
