/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util.proto;

import android.annotation.TestApi;
import android.util.Log;

import java.util.ArrayList;

/**
 * A stream of bytes containing a read pointer and a write pointer,
 * backed by a set of fixed-size buffers.  There are write functions for the
 * primitive types stored by protocol buffers, but none of the logic
 * for tags, inner objects, or any of that.
 *
 * Terminology:
 *      *Pos:       Position in the whole data set (as if it were a single buffer).
 *      *Index:     Position within a buffer.
 *      *BufIndex:  Index of a buffer within the mBuffers list
 * @hide
 */
@TestApi
public final class EncodedBuffer {
    private static final String TAG = "EncodedBuffer";

    private final ArrayList<byte[]> mBuffers = new ArrayList<byte[]>();

    private final int mChunkSize;

    /**
     * The number of buffers in mBuffers. Stored separately to avoid the extra
     * function call to size() everywhere for bounds checking.
     */
    private int mBufferCount;

    /**
     * The buffer we are currently writing to.
     */
    private byte[] mWriteBuffer;

    /**
     * The index into mWriteBuffer that we will write to next.
     * It may point to the end of the buffer, in which case,
     * the NEXT write will allocate a new buffer.
     */
    private int mWriteIndex;

    /**
     * The index of mWriteBuffer in mBuffers.
     */
    private int mWriteBufIndex;

    /**
     * The buffer we are currently reading from.
     */
    private byte[] mReadBuffer;

    /**
     * The index of mReadBuffer in mBuffers.
     */
    private int mReadBufIndex;

    /**
     * The index into mReadBuffer that we will read from next.
     * It may point to the end of the buffer, in which case,
     * the NEXT read will advance to the next buffer.
     */
    private int mReadIndex;

    /**
     * The amount of data in the last buffer.
     */
    private int mReadLimit = -1;

    /**
     * How much data there is total.
     */
    private int mReadableSize = -1;

    public EncodedBuffer() {
        this(0);
    }

    /**
     * Construct an EncodedBuffer object.
     *
     * @param chunkSize The size of the buffers to use.  If chunkSize &lt;= 0, a default
     *                  size will be used instead.
     */
    public EncodedBuffer(int chunkSize) {
        if (chunkSize <= 0) {
            chunkSize = 8 * 1024;
        }
        mChunkSize = chunkSize;
        mWriteBuffer = new byte[mChunkSize];
        mBuffers.add(mWriteBuffer);
        mBufferCount = 1;
    }

    //
    // Buffer management.
    //

    /**
     * Rewind the read and write pointers, and record how much data was last written.
     */
    public void startEditing() {
        mReadableSize = ((mWriteBufIndex) * mChunkSize) + mWriteIndex;
        mReadLimit = mWriteIndex;

        mWriteBuffer = mBuffers.get(0);
        mWriteIndex = 0;
        mWriteBufIndex = 0;

        mReadBuffer = mWriteBuffer;
        mReadBufIndex = 0;
        mReadIndex = 0;
    }

    /**
     * Rewind the read pointer. Don't touch the write pointer.
     */
    public void rewindRead() {
        mReadBuffer = mBuffers.get(0);
        mReadBufIndex = 0;
        mReadIndex = 0;
    }

    /**
     * Only valid after startEditing. Returns -1 before that.
     */
    public int getReadableSize() {
        return mReadableSize;
    }

    /**
     * Returns the buffer size
     * @return the buffer size
     */
    public int getSize() {
        return ((mBufferCount - 1) * mChunkSize) + mWriteIndex;
    }

    //
    // Reading from the read position.
    //

    /**
     * Only valid after startEditing.
     */
    public int getReadPos() {
        return ((mReadBufIndex) * mChunkSize) + mReadIndex;
    }

    /**
     * Skip over _amount_ bytes.
     */
    public void skipRead(int amount) {
        if (amount < 0) {
            throw new RuntimeException("skipRead with negative amount=" + amount);
        }
        if (amount == 0) {
            return;
        }
        if (amount <= mChunkSize - mReadIndex) {
            mReadIndex += amount;
        } else {
            amount -= mChunkSize - mReadIndex;
            mReadIndex = amount % mChunkSize;
            if (mReadIndex == 0) {
                mReadIndex = mChunkSize;
                mReadBufIndex += (amount / mChunkSize);
            } else {
                mReadBufIndex += 1 + (amount / mChunkSize);
            }
            mReadBuffer = mBuffers.get(mReadBufIndex);
        }
    }

    /**
     * Read one byte from the stream and advance the read pointer.
     *
     * @throws IndexOutOfBoundsException if the read point is past the end of
     * the buffer or past the read limit previously set by startEditing().
     */
    public byte readRawByte() {
        if (mReadBufIndex > mBufferCount
                || (mReadBufIndex == mBufferCount - 1 && mReadIndex >= mReadLimit)) {
            throw new IndexOutOfBoundsException("Trying to read too much data"
                    + " mReadBufIndex=" + mReadBufIndex + " mBufferCount=" + mBufferCount
                    + " mReadIndex=" + mReadIndex + " mReadLimit=" + mReadLimit);
        }
        if (mReadIndex >= mChunkSize) {
            mReadBufIndex++;
            mReadBuffer = mBuffers.get(mReadBufIndex);
            mReadIndex = 0;
        }
        return mReadBuffer[mReadIndex++];
    }

    /**
     * Read an unsigned varint. The value will be returend in a java signed long.
     */
    public long readRawUnsigned() {
        int bits = 0;
        long result = 0;
        while (true) {
            final byte b = readRawByte();
            result |= ((long)(b & 0x7F)) << bits;
            if ((b & 0x80) == 0) {
                return result;
            }
            bits += 7;
            if (bits > 64) {
                throw new ProtoParseException("Varint too long -- " + getDebugString());
            }
        }
    }

    /**
     * Read 32 little endian bits from the stream.
     */
    public int readRawFixed32() {
        return (readRawByte() & 0x0ff)
                | ((readRawByte() & 0x0ff) << 8)
                | ((readRawByte() & 0x0ff) << 16)
                | ((readRawByte() & 0x0ff) << 24);
    }

    //
    // Writing at a the end of the stream.
    //

    /**
     * Advance to the next write buffer, allocating it if necessary.
     *
     * Must be called immediately <b>before</b> the next write, not after a write,
     * so that a dangling empty buffer is not created.  Doing so will interfere
     * with the expectation that mWriteIndex will point past the end of the buffer
     * until the next read happens.
     */
    private void nextWriteBuffer() {
        mWriteBufIndex++;
        if (mWriteBufIndex >= mBufferCount) {
            mWriteBuffer = new byte[mChunkSize];
            mBuffers.add(mWriteBuffer);
            mBufferCount++;
        } else {
            mWriteBuffer = mBuffers.get(mWriteBufIndex);
        }
        mWriteIndex = 0;
    }

    /**
     * Write a single byte to the stream.
     */
    public void writeRawByte(byte val) {
        if (mWriteIndex >= mChunkSize) {
            nextWriteBuffer();
        }
        mWriteBuffer[mWriteIndex++] = val;
    }

    /**
     * Return how many bytes a 32 bit unsigned varint will take when written to the stream.
     */
    public static int getRawVarint32Size(int val) {
        if ((val & (0xffffffff << 7)) == 0) return 1;
        if ((val & (0xffffffff << 14)) == 0) return 2;
        if ((val & (0xffffffff << 21)) == 0) return 3;
        if ((val & (0xffffffff << 28)) == 0) return 4;
        return 5;
    }

    /**
     * Write an unsigned varint to the stream. A signed value would need to take 10 bytes.
     *
     * @param val treated as unsigned.
     */
    public void writeRawVarint32(int val) {
        while (true) {
            if ((val & ~0x7F) == 0) {
                writeRawByte((byte)val);
                return;
            } else {
                writeRawByte((byte)((val & 0x7F) | 0x80));
                val >>>= 7;
            }
        }
    }

    /**
     * Return how many bytes a 32 bit signed zig zag value will take when written to the stream.
     */
    public static int getRawZigZag32Size(int val) {
        return getRawVarint32Size(zigZag32(val));
    }

    /**
     *  Write a zig-zag encoded value.
     *
     *  @param val treated as signed
     */
    public void writeRawZigZag32(int val) {
        writeRawVarint32(zigZag32(val));
    }

    /**
     * Return how many bytes a 64 bit varint will take when written to the stream.
     */
    public static int getRawVarint64Size(long val) {
        if ((val & (0xffffffffffffffffL << 7)) == 0) return 1;
        if ((val & (0xffffffffffffffffL << 14)) == 0) return 2;
        if ((val & (0xffffffffffffffffL << 21)) == 0) return 3;
        if ((val & (0xffffffffffffffffL << 28)) == 0) return 4;
        if ((val & (0xffffffffffffffffL << 35)) == 0) return 5;
        if ((val & (0xffffffffffffffffL << 42)) == 0) return 6;
        if ((val & (0xffffffffffffffffL << 49)) == 0) return 7;
        if ((val & (0xffffffffffffffffL << 56)) == 0) return 8;
        if ((val & (0xffffffffffffffffL << 63)) == 0) return 9;
        return 10;
    }

    /**
     * Write a 64 bit varint to the stream.
     */
    public void writeRawVarint64(long val) {
        while (true) {
            if ((val & ~0x7FL) == 0) {
                writeRawByte((byte)val);
                return;
            } else {
                writeRawByte((byte)((val & 0x7F) | 0x80));
                val >>>= 7;
            }
        }
    }

    /**
     * Return how many bytes a signed 64 bit zig zag value will take when written to the stream.
     */
    public static int getRawZigZag64Size(long val) {
        return getRawVarint64Size(zigZag64(val));
    }

    /**
     * Write a 64 bit signed zig zag value to the stream.
     */
    public void writeRawZigZag64(long val) {
        writeRawVarint64(zigZag64(val));
    }

    /**
     * Write 4 little endian bytes to the stream.
     */
    public void writeRawFixed32(int val) {
        writeRawByte((byte)(val));
        writeRawByte((byte)(val >> 8));
        writeRawByte((byte)(val >> 16));
        writeRawByte((byte)(val >> 24));
    }

    /**
     * Write 8 little endian bytes to the stream.
     */
    public void writeRawFixed64(long val) {
        writeRawByte((byte)(val));
        writeRawByte((byte)(val >> 8));
        writeRawByte((byte)(val >> 16));
        writeRawByte((byte)(val >> 24));
        writeRawByte((byte)(val >> 32));
        writeRawByte((byte)(val >> 40));
        writeRawByte((byte)(val >> 48));
        writeRawByte((byte)(val >> 56));
    }

    /**
     * Write a buffer to the stream. Writes nothing if val is null or zero-length.
     */
    public void writeRawBuffer(byte[] val) {
        if (val != null && val.length > 0) {
            writeRawBuffer(val, 0, val.length);
        }
    }

    /**
     * Write part of an array of bytes.
     */
    public void writeRawBuffer(byte[] val, int offset, int length) {
        if (val == null) {
            return;
        }
        // Write up to the amount left in the first chunk to write.
        int amt = length < (mChunkSize - mWriteIndex) ? length : (mChunkSize - mWriteIndex);
        if (amt > 0) {
            System.arraycopy(val, offset, mWriteBuffer, mWriteIndex, amt);
            mWriteIndex += amt;
            length -= amt;
            offset += amt;
        }
        while (length > 0) {
            // We know we're now at the beginning of a chunk
            nextWriteBuffer();
            amt = length < mChunkSize ? length : mChunkSize;
            System.arraycopy(val, offset, mWriteBuffer, mWriteIndex, amt);
            mWriteIndex += amt;
            length -= amt;
            offset += amt;
        }
    }

    /**
     * Copies data _size_ bytes of data within this buffer from _srcOffset_
     * to the current write position. Like memmov but handles the chunked buffer.
     */
    public void writeFromThisBuffer(int srcOffset, int size) {
        if (mReadLimit < 0) {
            throw new IllegalStateException("writeFromThisBuffer before startEditing");
        }
        if (srcOffset < getWritePos()) {
            throw new IllegalArgumentException("Can only move forward in the buffer --"
                    + " srcOffset=" + srcOffset + " size=" + size + " " + getDebugString());
        }
        if (srcOffset + size > mReadableSize) {
            throw new IllegalArgumentException("Trying to move more data than there is --"
                    + " srcOffset=" + srcOffset + " size=" + size + " " + getDebugString());
        }
        if (size == 0) {
            return;
        }
        if (srcOffset == ((mWriteBufIndex) * mChunkSize) + mWriteIndex /* write pos */) {
            // Writing to the same location. Just advance the write pointer.  We already
            // checked that size is in bounds, so we don't need to do any more range
            // checking.
            if (size <= mChunkSize - mWriteIndex) {
                mWriteIndex += size;
            } else {
                size -= mChunkSize - mWriteIndex;
                mWriteIndex = size % mChunkSize;
                if (mWriteIndex == 0) {
                    // Roll it back so nextWriteBuffer can do its job
                    // on the next call (also makes mBuffers.get() not
                    // fail if we're at the end).
                    mWriteIndex = mChunkSize;
                    mWriteBufIndex += (size / mChunkSize);
                } else {
                    mWriteBufIndex += 1 + (size / mChunkSize);
                }
                mWriteBuffer = mBuffers.get(mWriteBufIndex);
            }
        } else {
            // Loop through the buffer, copying as much as we can each time.
            // We already bounds checked so we don't need to do it again here,
            // and nextWriteBuffer will never allocate.
            int readBufIndex = srcOffset / mChunkSize;
            byte[] readBuffer = mBuffers.get(readBufIndex);
            int readIndex = srcOffset % mChunkSize;
            while (size > 0) {
                if (mWriteIndex >= mChunkSize) {
                    nextWriteBuffer();
                }
                if (readIndex >= mChunkSize) {
                    readBufIndex++;
                    readBuffer = mBuffers.get(readBufIndex);
                    readIndex = 0;
                }
                final int spaceInWriteBuffer = mChunkSize - mWriteIndex;
                final int availableInReadBuffer = mChunkSize - readIndex;
                final int amt = Math.min(size, Math.min(spaceInWriteBuffer, availableInReadBuffer));
                System.arraycopy(readBuffer, readIndex, mWriteBuffer, mWriteIndex, amt);
                mWriteIndex += amt;
                readIndex += amt;
                size -= amt;
            }
        }
    }

    //
    // Writing at a particular location.
    //

    /**
     * Returns the index into the virtual array of the write pointer.
     */
    public int getWritePos() {
        return ((mWriteBufIndex) * mChunkSize) + mWriteIndex;
    }

    /**
     * Resets the write pointer to a virtual location as returned by getWritePos.
     */
    public void rewindWriteTo(int writePos) {
        if (writePos > getWritePos()) {
            throw new RuntimeException("rewindWriteTo only can go backwards" + writePos);
        }
        mWriteBufIndex = writePos / mChunkSize;
        mWriteIndex = writePos % mChunkSize;
        if (mWriteIndex == 0 && mWriteBufIndex != 0) {
            // Roll back so nextWriteBuffer can do its job on the next call
            // but at the first write we're at 0.
            mWriteIndex = mChunkSize;
            mWriteBufIndex--;
        }
        mWriteBuffer = mBuffers.get(mWriteBufIndex);
    }

    /**
     * Read a 32 bit value from the stream.
     *
     * Doesn't touch or affect mWritePos.
     */
    public int getRawFixed32At(int pos) {
        return (0x00ff & (int)mBuffers.get(pos / mChunkSize)[pos % mChunkSize])
                | ((0x0ff & (int)mBuffers.get((pos+1) / mChunkSize)[(pos+1) % mChunkSize]) << 8)
                | ((0x0ff & (int)mBuffers.get((pos+2) / mChunkSize)[(pos+2) % mChunkSize]) << 16)
                | ((0x0ff & (int)mBuffers.get((pos+3) / mChunkSize)[(pos+3) % mChunkSize]) << 24);
    }

    /**
     * Overwrite a 32 bit value in the stream.
     *
     * Doesn't touch or affect mWritePos.
     */
    public void editRawFixed32(int pos, int val) {
        mBuffers.get(pos / mChunkSize)[pos % mChunkSize] = (byte)(val);
        mBuffers.get((pos+1) / mChunkSize)[(pos+1) % mChunkSize] = (byte)(val >> 8);
        mBuffers.get((pos+2) / mChunkSize)[(pos+2) % mChunkSize] = (byte)(val >> 16);
        mBuffers.get((pos+3) / mChunkSize)[(pos+3) % mChunkSize] = (byte)(val >> 24);
    }

    //
    // Zigging and zagging
    //

    /**
     * Zig-zag encode a 32 bit value.
     */
    private static int zigZag32(int val) {
        return (val << 1) ^ (val >> 31);
    }

    /**
     * Zig-zag encode a 64 bit value.
     */
    private static long zigZag64(long val) {
        return (val << 1) ^ (val >> 63);
    }

    //
    // Debugging / testing
    //
    // VisibleForTesting

    /**
     * Get a copy of the first _size_ bytes of data. This is not range
     * checked, and if the bounds are outside what has been written you will
     * get garbage and if it is outside the buffers that have been allocated,
     * you will get an exception.
     */
    public byte[] getBytes(int size) {
        final byte[] result = new byte[size];

        final int bufCount = size / mChunkSize;
        int bufIndex;
        int writeIndex = 0;

        for (bufIndex=0; bufIndex<bufCount; bufIndex++) {
            System.arraycopy(mBuffers.get(bufIndex), 0, result, writeIndex, mChunkSize);
            writeIndex += mChunkSize;
        }

        final int lastSize = size - (bufCount * mChunkSize);
        if (lastSize > 0) {
            System.arraycopy(mBuffers.get(bufIndex), 0, result, writeIndex, lastSize);
        }

        return result;
    }

    /**
     * Get the number of chunks allocated.
     */
    // VisibleForTesting
    public int getChunkCount() {
        return mBuffers.size();
    }

    /**
     * Get the write position inside the current write chunk.
     */
     // VisibleForTesting
    public int getWriteIndex() {
        return mWriteIndex;
    }

    /**
     * Get the index of the current write chunk in the list of chunks.
     */
    // VisibleForTesting
    public int getWriteBufIndex() {
        return mWriteBufIndex;
    }

    /**
     * Return debugging information about this EncodedBuffer object.
     */
    public String getDebugString() {
        return "EncodedBuffer( mChunkSize=" + mChunkSize + " mBuffers.size=" + mBuffers.size()
                + " mBufferCount=" + mBufferCount + " mWriteIndex=" + mWriteIndex
                + " mWriteBufIndex=" + mWriteBufIndex + " mReadBufIndex=" + mReadBufIndex
                + " mReadIndex=" + mReadIndex + " mReadableSize=" + mReadableSize
                + " mReadLimit=" + mReadLimit + " )";
    }

    /**
     * Print the internal buffer chunks.
     */
    public void dumpBuffers(String tag) {
        final int N = mBuffers.size();
        int start = 0;
        for (int i=0; i<N; i++) {
            start += dumpByteString(tag, "{" + i + "} ", start, mBuffers.get(i));
        }
    }

    /**
     * Print the internal buffer chunks.
     */
    public static void dumpByteString(String tag, String prefix, byte[] buf) {
        dumpByteString(tag, prefix, 0, buf);
    }

    /**
     * Print the internal buffer chunks.
     */
    private static int dumpByteString(String tag, String prefix, int start, byte[] buf) {
        StringBuilder sb = new StringBuilder();
        final int length = buf.length;
        final int lineLen = 16;
        int i;
        for (i=0; i<length; i++) {
            if (i % lineLen == 0) {
                if (i != 0) {
                    Log.d(tag, sb.toString());
                    sb = new StringBuilder();
                }
                sb.append(prefix);
                sb.append('[');
                sb.append(start + i);
                sb.append(']');
                sb.append(' ');
            } else {
                sb.append(' ');
            }
            byte b = buf[i];
            byte c = (byte)((b >> 4) & 0x0f);
            if (c < 10) {
                sb.append((char)('0' + c));
            } else {
                sb.append((char)('a' - 10 + c));
            }
            byte d = (byte)(b & 0x0f);
            if (d < 10) {
                sb.append((char)('0' + d));
            } else {
                sb.append((char)('a' - 10 + d));
            }
        }
        Log.d(tag, sb.toString());
        return length;
    }
}
