// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2015-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.nio.ByteBuffer;

import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.UResourceTypeMismatchException;

// Class UResource is named consistently with the public class UResourceBundle,
// in case we want to make it public at some point.

/**
 * ICU resource bundle key and value types.
 */
public final class UResource {
    /**
     * Represents a resource bundle item's key string.
     * Avoids object creations as much as possible.
     * Mutable, not thread-safe.
     * For permanent storage, use clone() or toString().
     */
    public static final class Key implements CharSequence, Cloneable, Comparable<Key> {
        // Stores a reference to the resource bundle key string bytes array,
        // with an offset of the key, to avoid creating a String object
        // until one is really needed.
        // Alternatively, we could try to always just get the key String object,
        // and cache it in the reader, and see if that performs better or worse.
        private byte[] bytes;
        private int offset;
        private int length;
        private String s;

        /**
         * Constructs an empty resource key string object.
         */
        public Key() {
            s = "";
        }

        /**
         * Constructs a resource key object equal to the given string.
         */
        public Key(String s) {
            setString(s);
        }

        private Key(byte[] keyBytes, int keyOffset, int keyLength) {
            bytes = keyBytes;
            offset = keyOffset;
            length = keyLength;
        }

        /**
         * Mutates this key for a new NUL-terminated resource key string.
         * The corresponding ASCII-character bytes are not copied and
         * must not be changed during the lifetime of this key
         * (or until the next setBytes() call)
         * and lifetimes of subSequences created from this key.
         *
         * @param keyBytes new key string byte array
         * @param keyOffset new key string offset
         */
        public Key setBytes(byte[] keyBytes, int keyOffset) {
            bytes = keyBytes;
            offset = keyOffset;
            for (length = 0; keyBytes[keyOffset + length] != 0; ++length) {}
            s = null;
            return this;
        }

        /**
         * Mutates this key to an empty resource key string.
         */
        public Key setToEmpty() {
            bytes = null;
            offset = length = 0;
            s = "";
            return this;
        }

        /**
         * Mutates this key to be equal to the given string.
         */
        public Key setString(String s) {
            if (s.isEmpty()) {
                setToEmpty();
            } else {
                bytes = new byte[s.length()];
                offset = 0;
                length = s.length();
                for (int i = 0; i < length; ++i) {
                    char c = s.charAt(i);
                    if (c <= 0x7f) {
                        bytes[i] = (byte)c;
                    } else {
                        throw new IllegalArgumentException('\"' + s + "\" is not an ASCII string");
                    }
                }
                this.s = s;
            }
            return this;
        }

        /**
         * {@inheritDoc}
         * Does not clone the byte array.
         */
        @Override
        public Key clone() {
            try {
                return (Key)super.clone();
            } catch (CloneNotSupportedException cannotOccur) {
                return null;
            }
        }

        @Override
        public char charAt(int i) {
            assert(0 <= i && i < length);
            return (char)bytes[offset + i];
        }

        @Override
        public int length() {
            return length;
        }

        @Override
        public Key subSequence(int start, int end) {
            assert(0 <= start && start < length);
            assert(start <= end && end <= length);
            return new Key(bytes, offset + start, end - start);
        }

        /**
         * Creates/caches/returns this resource key string as a Java String.
         */
        public String toString() {
            if (s == null) {
                s = internalSubString(0, length);
            }
            return s;
        }

        private String internalSubString(int start, int end) {
            StringBuilder sb = new StringBuilder(end - start);
            for (int i = start; i < end; ++i) {
                sb.append((char)bytes[offset + i]);
            }
            return sb.toString();
        }

        /**
         * Creates a new Java String for a sub-sequence of this resource key string.
         */
        public String substring(int start) {
            assert(0 <= start && start < length);
            return internalSubString(start, length);
        }

        /**
         * Creates a new Java String for a sub-sequence of this resource key string.
         */
        public String substring(int start, int end) {
            assert(0 <= start && start < length);
            assert(start <= end && end <= length);
            return internalSubString(start, end);
        }

        private boolean regionMatches(byte[] otherBytes, int otherOffset, int n) {
            for (int i = 0; i < n; ++i) {
                if (bytes[offset + i] != otherBytes[otherOffset + i]) {
                    return false;
                }
            }
            return true;
        }

        private boolean regionMatches(int start, CharSequence cs, int n) {
            for (int i = 0; i < n; ++i) {
                if (bytes[offset + start + i] != cs.charAt(i)) {
                    return false;
                }
            }
            return true;
        }

        @Override
        public boolean equals(Object other) {
            if (other == null) {
                return false;
            } else if (this == other) {
                return true;
            } else if (other instanceof Key) {
                Key otherKey = (Key)other;
                return length == otherKey.length &&
                        regionMatches(otherKey.bytes, otherKey.offset, length);
            } else {
                return false;
            }
        }

        public boolean contentEquals(CharSequence cs) {
            if (cs == null) {
                return false;
            }
            return this == cs || (cs.length() == length && regionMatches(0, cs, length));
        }

        public boolean startsWith(CharSequence cs) {
            int csLength = cs.length();
            return csLength <= length && regionMatches(0, cs, csLength);
        }

        public boolean endsWith(CharSequence cs) {
            int csLength = cs.length();
            return csLength <= length && regionMatches(length - csLength, cs, csLength);
        }

        /**
         * @return true if the substring of this key starting from the offset
         *         contains the same characters as the other sequence.
         */
        public boolean regionMatches(int start, CharSequence cs) {
            int csLength = cs.length();
            return csLength == (length - start) && regionMatches(start, cs, csLength);
        }

        @Override
        public int hashCode() {
            // Never return s.hashCode(), so that
            // Key.hashCode() is the same whether we have cached s or not.
            if (length == 0) {
                return 0;
            }

            int h = bytes[offset];
            for (int i = 1; i < length; ++i) {
                h = 37 * h + bytes[offset];
            }
            return h;
        }

        @Override
        public int compareTo(Key other) {
            return compareTo((CharSequence)other);
        }

        public int compareTo(CharSequence cs) {
            int csLength = cs.length();
            int minLength = length <= csLength ? length : csLength;
            for (int i = 0; i < minLength; ++i) {
                int diff = (int)charAt(i) - (int)cs.charAt(i);
                if (diff != 0) {
                    return diff;
                }
            }
            return length - csLength;
        }
    }

    /**
     * Interface for iterating over a resource bundle array resource.
     * Does not use Java Iterator to reduce object creations.
     */
    public interface Array {
        /**
         * @return The number of items in the array resource.
         */
        public int getSize();
        /**
         * @param i Array item index.
         * @param value Output-only, receives the value of the i'th item.
         * @return true if i is non-negative and less than getSize().
         */
        public boolean getValue(int i, Value value);
    }

    /**
     * Interface for iterating over a resource bundle table resource.
     * Does not use Java Iterator to reduce object creations.
     */
    public interface Table {
        /**
         * @return The number of items in the array resource.
         */
        public int getSize();
        /**
         * @param i Array item index.
         * @param key Output-only, receives the key of the i'th item.
         * @param value Output-only, receives the value of the i'th item.
         * @return true if i is non-negative and less than getSize().
         */
        public boolean getKeyAndValue(int i, Key key, Value value);
    }

    /**
     * Represents a resource bundle item's value.
     * Avoids object creations as much as possible.
     * Mutable, not thread-safe.
     */
    public static abstract class Value {
        protected Value() {}

        /**
         * @return ICU resource type like {@link UResourceBundle#getType()},
         *     for example, {@link UResourceBundle#STRING}
         */
        public abstract int getType();

        /**
         * @see UResourceBundle#getString()
         * @throws UResourceTypeMismatchException if this is not a string resource
         */
        public abstract String getString();

        /**
         * @throws UResourceTypeMismatchException if this is not an alias resource
         */
        public abstract String getAliasString();

        /**
         * @see UResourceBundle#getInt()
         * @throws UResourceTypeMismatchException if this is not an integer resource
         */
        public abstract int getInt();

        /**
         * @see UResourceBundle#getUInt()
         * @throws UResourceTypeMismatchException if this is not an integer resource
         */
        public abstract int getUInt();

        /**
         * @see UResourceBundle#getIntVector()
         * @throws UResourceTypeMismatchException if this is not an intvector resource
         */
        public abstract int[] getIntVector();

        /**
         * @see UResourceBundle#getBinary()
         * @throws UResourceTypeMismatchException if this is not a binary-blob resource
         */
        public abstract ByteBuffer getBinary();

        /**
         * @throws UResourceTypeMismatchException if this is not an array resource
         */
        public abstract Array getArray();

        /**
         * @throws UResourceTypeMismatchException if this is not a table resource
         */
        public abstract Table getTable();

        /**
         * Is this a no-fallback/no-inheritance marker string?
         * Such a marker is used for CLDR no-fallback data values of "∅∅∅"
         * when enumerating tables with fallback from the specific resource bundle to root.
         *
         * @return true if this is a no-inheritance marker string
         */
        public abstract boolean isNoInheritanceMarker();

        /**
         * @return the array of strings in this array resource.
         * @see UResourceBundle#getStringArray()
         * @throws UResourceTypeMismatchException if this is not an array resource
         *     or if any of the array items is not a string
         */
        public abstract String[] getStringArray();

        /**
         * Same as
         * <pre>
         * if (getType() == STRING) {
         *     return new String[] { getString(); }
         * } else {
         *     return getStringArray();
         * }
         * </pre>
         *
         * @see #getString()
         * @see #getStringArray()
         * @throws UResourceTypeMismatchException if this is
         *     neither a string resource nor an array resource containing strings
         */
        public abstract String[] getStringArrayOrStringAsArray();

        /**
         * Same as
         * <pre>
         * if (getType() == STRING) {
         *     return getString();
         * } else {
         *     return getStringArray()[0];
         * }
         * </pre>
         *
         * @see #getString()
         * @see #getStringArray()
         * @throws UResourceTypeMismatchException if this is
         *     neither a string resource nor an array resource containing strings
         */
        public abstract String getStringOrFirstOfArray();

        /**
         * Only for debugging.
         */
        @Override
        public String toString() {
            switch(getType()) {
            case UResourceBundle.STRING:
                return getString();
            case UResourceBundle.INT:
                return Integer.toString(getInt());
            case UResourceBundle.INT_VECTOR:
                int[] iv = getIntVector();
                StringBuilder sb = new StringBuilder("[");
                sb.append(iv.length).append("]{");
                if (iv.length != 0) {
                    sb.append(iv[0]);
                    for (int i = 1; i < iv.length; ++i) {
                        sb.append(", ").append(iv[i]);
                    }
                }
                return sb.append('}').toString();
            case UResourceBundle.BINARY:
                return "(binary blob)";
            case UResourceBundle.ARRAY:
                return "(array)";
            case UResourceBundle.TABLE:
                return "(table)";
            default:  // should not occur
                return "???";
            }
        }
    }

    /**
     * Sink for ICU resource bundle contents.
     */
    public static abstract class Sink {
        /**
         * Called once for each bundle (child-parent-...-root).
         * The value is normally an array or table resource,
         * and implementations of this method normally iterate over the
         * tree of resource items stored there.
         *
         * @param key Initially the key string of the enumeration-start resource.
         *     Empty if the enumeration starts at the top level of the bundle.
         *     Reuse for output values from Array and Table getters.
         * @param value Call getArray() or getTable() as appropriate.
         *     Then reuse for output values from Array and Table getters.
         * @param noFallback true if the bundle has no parent;
         *     that is, its top-level table has the nofallback attribute,
         *     or it is the root bundle of a locale tree.
         */
        public abstract void put(Key key, Value value, boolean noFallback);
    }

    /**
     * Sink for ICU resource array contents.
     * The base class does nothing.
     *
     * <p>Nested arrays and tables are stored as nested sinks,
     * never put() as {@link Value} items.
     */
    public static class ArraySink {
        /**
         * "Enters" the array.
         * Called just before enumerating the array's resource items.
         * The size can be used to allocate storage for the items.
         * It may differ between child and parent bundles.
         *
         * @param size number of array items
         */
        public void enter(int size) {}

        /**
         * Adds a value from a resource array.
         *
         * @param index of the resource array item
         * @param value resource value
         */
        public void put(int index, Value value) {}

        /**
         * Returns a nested resource array at the array index as another sink.
         * Creates the sink if none exists for the key.
         * Returns null if nested arrays are not supported.
         * The default implementation always returns null.
         *
         * @param index of the resource array item
         * @return nested-array sink, or null
         */
        public ArraySink getOrCreateArraySink(int index) {
            return null;
        }

        /**
         * Returns a nested resource table at the array index as another sink.
         * Creates the sink if none exists for the key.
         * Returns null if nested tables are not supported.
         * The default implementation always returns null.
         *
         * @param index of the resource array item
         * @return nested-table sink, or null
         */
        public TableSink getOrCreateTableSink(int index) {
            return null;
        }

        /**
         * "Leaves" the array.
         * Indicates that all of the resources and sub-resources of the current array
         * have been enumerated.
         */
        public void leave() {}
    }

    /**
     * Sink for ICU resource table contents.
     * The base class does nothing.
     *
     * <p>Nested arrays and tables are stored as nested sinks,
     * never put() as {@link Value} items.
     */
    public static class TableSink {
        /**
         * "Enters" the table.
         * Called just before enumerating the table's resource items.
         * The size can be used to allocate storage for the items.
         * It usually differs between child and parent bundles.
         *
         * @param size number of table items
         */
        public void enter(int size) {}

        /**
         * Adds a key-value pair from a resource table.
         *
         * @param key resource key string
         * @param value resource value
         */
        public void put(Key key, Value value) {}

        /**
         * Adds a no-fallback/no-inheritance marker for this key.
         * Used for CLDR no-fallback data values of "∅∅∅"
         * when enumerating tables with fallback from the specific resource bundle to root.
         *
         * <p>The default implementation does nothing.
         *
         * @param key to be removed
         */
        public void putNoFallback(Key key) {}

        /**
         * Returns a nested resource array for the key as another sink.
         * Creates the sink if none exists for the key.
         * Returns null if nested arrays are not supported.
         * The default implementation always returns null.
         *
         * @param key resource key string
         * @return nested-array sink, or null
         */
        public ArraySink getOrCreateArraySink(Key key) {
            return null;
        }

        /**
         * Returns a nested resource table for the key as another sink.
         * Creates the sink if none exists for the key.
         * Returns null if nested tables are not supported.
         * The default implementation always returns null.
         *
         * @param key resource key string
         * @return nested-table sink, or null
         */
        public TableSink getOrCreateTableSink(Key key) {
            return null;
        }

        /**
         * "Leaves" the table.
         * Indicates that all of the resources and sub-resources of the current table
         * have been enumerated.
         */
        public void leave() {}
    }
}
