package anastore.util;

import anastore.store.Storable;
import anastore.store.StorableFactory;

import java.nio.ByteBuffer;

/**
 * The block data, as stored in the cache.  Block data is immutable.
 */
public class BlockData implements Storable
{
    private final ByteBuffer _buf;

    /**
     * Construct a new block with the given data.  The given byte
     * array <i>must not</i> be modified after this is constructed.
     */
    public BlockData(byte[] data)
    {
        _buf = ByteBuffer.wrap(data);
    }

    /**
     * Construct a new block backed by the data in the given byte
     * buffer.  The byte buffer must be writable, backed by an array,
     * and positioned at 0.  It's contents and pointers <i>must
     * not</i> be modified after this is constructed.
     */
    public BlockData(ByteBuffer buf)
    {
        assert !buf.isReadOnly();
        assert buf.hasArray();
        assert buf.position() == 0;
        _buf = buf;
    }

    public int getDataSize()
    {
        return _buf.limit();
    }

    public byte[] getData()
    {
        return _buf.array();
    }

    /**
     * Construct a read-only byte buffer backed by the data in this
     * block.  Since block data is immutable, the data in this byte
     * array is guaranteed not to change.  This byte buffer will be
     * independent of any byte buffers returned by other invocations
     * of this method.
     */
    public ByteBuffer toROByteBuffer()
    {
        return _buf.asReadOnlyBuffer();
    }

    /**
     * Copy the data in this block into a writable byte buffer.
     */
    public ByteBuffer copyToRWByteBuffer()
    {
        byte[] oldData = _buf.array();
        byte[] newData = new byte[oldData.length];
        System.arraycopy(oldData, 0, newData, 0, newData.length);
        return ByteBuffer.wrap(newData);
    }

    private static class Factory implements StorableFactory<BlockData>
    {
        public BlockData fromData(byte[] data)
        {
            return new BlockData(data);
        }
    }

    public static final Factory FACTORY = new Factory();

    @Override
    public String toString()
    {
        return "BlockData<" + HexDump.summarize(_buf.array(), 5) + ">";
    }
}
