/*
*******************************************************************************
*   Copyright (C) 2011-2013, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*   created on: 2011jan05
*   created by: Markus W. Scherer
*   ported from ICU4C bytestriebuilder.h/.cpp
*/

package com.ibm.icu.util;

import java.nio.ByteBuffer;

/**
 * Builder class for BytesTrie.
 *
 * <p>This class is not intended for public subclassing.
 *
 * @stable ICU 4.8
 * @author Markus W. Scherer
 */
public final class BytesTrieBuilder extends StringTrieBuilder {
    /**
     * Constructs an empty builder.
     * @stable ICU 4.8
     */
    public BytesTrieBuilder() {}

    // Used in add() to wrap the bytes into a CharSequence for StringTrieBuilder.addImpl().
    private static final class BytesAsCharSequence implements CharSequence {
        public BytesAsCharSequence(byte[] sequence, int length) {
            s=sequence;
            len=length;
        }
        public char charAt(int i) { return (char)(s[i]&0xff); }
        public int length() { return len; }
        public CharSequence subSequence(int start, int end) { return null; }

        private byte[] s;
        private int len;
    }

    /**
     * Adds a (byte sequence, value) pair.
     * The byte sequence must be unique.
     * Bytes 0..length-1 will be copied; the builder does not keep
     * a reference to the input array.
     * @param sequence The array that contains the byte sequence, starting at index 0.
     * @param length The length of the byte sequence.
     * @param value The value associated with this byte sequence.
     * @return this
     * @stable ICU 4.8
     */
    public BytesTrieBuilder add(byte[] sequence, int length, int value) {
        addImpl(new BytesAsCharSequence(sequence, length), value);
        return this;
    }

    /**
     * Builds a BytesTrie for the add()ed data.
     * Once built, no further data can be add()ed until clear() is called.
     *
     * <p>A BytesTrie cannot be empty. At least one (byte sequence, value) pair
     * must have been add()ed.
     *
     * <p>Multiple calls to build() or buildByteBuffer() return tries or buffers
     * which share the builder's byte array, without rebuilding.
     * <em>The byte array must not be modified via the buildByteBuffer() result object.</em>
     * After clear() has been called, a new array will be used.
     * @param buildOption Build option, see StringTrieBuilder.Option.
     * @return A new BytesTrie for the add()ed data.
     * @stable ICU 4.8
     */
    public BytesTrie build(StringTrieBuilder.Option buildOption) {
        buildBytes(buildOption);
        return new BytesTrie(bytes, bytes.length-bytesLength);
    }

    /**
     * Builds a BytesTrie for the add()ed data and byte-serializes it.
     * Once built, no further data can be add()ed until clear() is called.
     *
     * <p>A BytesTrie cannot be empty. At least one (byte sequence, value) pair
     * must have been add()ed.
     *
     * <p>Multiple calls to build() or buildByteBuffer() return tries or buffers
     * which share the builder's byte array, without rebuilding.
     * <em>Do not modify the bytes in the buffer!</em>
     * After clear() has been called, a new array will be used.
     *
     * <p>The serialized BytesTrie is accessible via the buffer's
     * array()/arrayOffset()+position() or remaining()/get(byte[]) etc.
     * @param buildOption Build option, see StringTrieBuilder.Option.
     * @return A ByteBuffer with the byte-serialized BytesTrie for the add()ed data.
     *         The buffer is not read-only and array() can be called.
     * @stable ICU 4.8
     */
    public ByteBuffer buildByteBuffer(StringTrieBuilder.Option buildOption) {
        buildBytes(buildOption);
        return ByteBuffer.wrap(bytes, bytes.length-bytesLength, bytesLength);
    }

    private void buildBytes(StringTrieBuilder.Option buildOption) {
        // Create and byte-serialize the trie for the elements.
        if(bytes==null) {
            bytes=new byte[1024];
        }
        buildImpl(buildOption);
    }

    /**
     * Removes all (byte sequence, value) pairs.
     * New data can then be add()ed and a new trie can be built.
     * @return this
     * @stable ICU 4.8
     */
    public BytesTrieBuilder clear() {
        clearImpl();
        bytes=null;
        bytesLength=0;
        return this;
    }

    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected boolean matchNodesCanHaveValues() /*const*/ { return false; }

    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int getMaxBranchLinearSubNodeLength() /*const*/ { return BytesTrie.kMaxBranchLinearSubNodeLength; }
    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int getMinLinearMatch() /*const*/ { return BytesTrie.kMinLinearMatch; }
    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int getMaxLinearMatchLength() /*const*/ { return BytesTrie.kMaxLinearMatchLength; }

    private void ensureCapacity(int length) {
        if(length>bytes.length) {
            int newCapacity=bytes.length;
            do {
                newCapacity*=2;
            } while(newCapacity<=length);
            byte[] newBytes=new byte[newCapacity];
            System.arraycopy(bytes, bytes.length-bytesLength,
                             newBytes, newBytes.length-bytesLength, bytesLength);
            bytes=newBytes;
        }
    }
    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int write(int b) {
        int newLength=bytesLength+1;
        ensureCapacity(newLength);
        bytesLength=newLength;
        bytes[bytes.length-bytesLength]=(byte)b;
        return bytesLength;
    }
    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int write(int offset, int length) {
        int newLength=bytesLength+length;
        ensureCapacity(newLength);
        bytesLength=newLength;
        int bytesOffset=bytes.length-bytesLength;
        while(length>0) {
            bytes[bytesOffset++]=(byte)strings.charAt(offset++);
            --length;
        }
        return bytesLength;
    }
    private int write(byte[] b, int length) {
        int newLength=bytesLength+length;
        ensureCapacity(newLength);
        bytesLength=newLength;
        System.arraycopy(b, 0, bytes, bytes.length-bytesLength, length);
        return bytesLength;
    }

    // For writeValueAndFinal() and writeDeltaTo().
    private final byte[] intBytes=new byte[5];

    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int writeValueAndFinal(int i, boolean isFinal) {
        if(0<=i && i<=BytesTrie.kMaxOneByteValue) {
            return write(((BytesTrie.kMinOneByteValueLead+i)<<1)|(isFinal?1:0));
        }
        int length=1;
        if(i<0 || i>0xffffff) {
            intBytes[0]=(byte)BytesTrie.kFiveByteValueLead;
            intBytes[1]=(byte)(i>>24);
            intBytes[2]=(byte)(i>>16);
            intBytes[3]=(byte)(i>>8);
            intBytes[4]=(byte)i;
            length=5;
        // } else if(i<=BytesTrie.kMaxOneByteValue) {
        //     intBytes[0]=(byte)(BytesTrie.kMinOneByteValueLead+i);
        } else {
            if(i<=BytesTrie.kMaxTwoByteValue) {
                intBytes[0]=(byte)(BytesTrie.kMinTwoByteValueLead+(i>>8));
            } else {
                if(i<=BytesTrie.kMaxThreeByteValue) {
                    intBytes[0]=(byte)(BytesTrie.kMinThreeByteValueLead+(i>>16));
                } else {
                    intBytes[0]=(byte)BytesTrie.kFourByteValueLead;
                    intBytes[1]=(byte)(i>>16);
                    length=2;
                }
                intBytes[length++]=(byte)(i>>8);
            }
            intBytes[length++]=(byte)i;
        }
        intBytes[0]=(byte)((intBytes[0]<<1)|(isFinal?1:0));
        return write(intBytes, length);
    }
    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int writeValueAndType(boolean hasValue, int value, int node) {
        int offset=write(node);
        if(hasValue) {
            offset=writeValueAndFinal(value, false);
        }
        return offset;
    }
    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    protected int writeDeltaTo(int jumpTarget) {
        int i=bytesLength-jumpTarget;
        assert(i>=0);
        if(i<=BytesTrie.kMaxOneByteDelta) {
            return write(i);
        }
        int length;
        if(i<=BytesTrie.kMaxTwoByteDelta) {
            intBytes[0]=(byte)(BytesTrie.kMinTwoByteDeltaLead+(i>>8));
            length=1;
        } else {
            if(i<=BytesTrie.kMaxThreeByteDelta) {
                intBytes[0]=(byte)(BytesTrie.kMinThreeByteDeltaLead+(i>>16));
                length=2;
            } else {
                if(i<=0xffffff) {
                    intBytes[0]=(byte)BytesTrie.kFourByteDeltaLead;
                    length=3;
                } else {
                    intBytes[0]=(byte)BytesTrie.kFiveByteDeltaLead;
                    intBytes[1]=(byte)(i>>24);
                    length=4;
                }
                intBytes[1]=(byte)(i>>16);
            }
            intBytes[1]=(byte)(i>>8);
        }
        intBytes[length++]=(byte)i;
        return write(intBytes, length);
    }

    // Byte serialization of the trie.
    // Grows from the back: bytesLength measures from the end of the buffer!
    private byte[] bytes;
    private int bytesLength;
}
