/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.qpid.server.bytebuffer;

import java.io.IOException;
import java.io.InputStream;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.ScatteringByteChannel;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

class SingleQpidByteBuffer implements QpidByteBuffer
{
    private static final AtomicIntegerFieldUpdater<SingleQpidByteBuffer>
            DISPOSED_UPDATER = AtomicIntegerFieldUpdater.newUpdater(
            SingleQpidByteBuffer.class,
            "_disposed");

    private final int _offset;
    private final ByteBufferRef _ref;
    private volatile ByteBuffer _buffer;

    @SuppressWarnings("unused")
    private volatile int _disposed;


    SingleQpidByteBuffer(ByteBufferRef ref)
    {
        this(ref, ref.getBuffer(), 0);
    }

    private SingleQpidByteBuffer(ByteBufferRef ref, ByteBuffer buffer, int offset)
    {
        _ref = ref;
        _buffer = buffer;
        _offset = offset;
        _ref.incrementRef(capacity());
    }

    @Override
    public final boolean isDirect()
    {
        return _buffer.isDirect();
    }

    @Override
    public final short getUnsignedByte()
    {
        return (short) (((short) get()) & 0xFF);
    }

    @Override
    public final int getUnsignedShort()
    {
        return ((int) getShort()) & 0xffff;
    }

    @Override
    public final int getUnsignedShort(int pos)
    {
        return ((int) getShort(pos)) & 0xffff;
    }

    @Override
    public final long getUnsignedInt()
    {
        return ((long) getInt()) & 0xffffffffL;
    }

    @Override
    public final SingleQpidByteBuffer putUnsignedByte(final short s)
    {
        put((byte) s);
        return this;
    }

    @Override
    public final SingleQpidByteBuffer putUnsignedShort(final int i)
    {
        putShort((short) i);
        return this;
    }

    @Override
    public final SingleQpidByteBuffer putUnsignedInt(final long value)
    {
        putInt((int) value);
        return this;
    }

    @Override
    public final void close()
    {
        dispose();
    }

    @Override
    public final void dispose()
    {
        if (DISPOSED_UPDATER.compareAndSet(this, 0, 1))
        {
            _ref.decrementRef(capacity());
        }
        _buffer = null;
    }

    @Override
    public final InputStream asInputStream()
    {
        final QpidByteBuffer buffer = this;
        return new QpidByteBufferInputStream(buffer);
    }

    @Override
    public final long read(ScatteringByteChannel channel) throws IOException
    {
        return channel.read(getUnderlyingBuffer());
    }

    @Override
    public String toString()
    {
        return "SingleQpidByteBuffer{" +
               "_buffer=" + _buffer +
               ", _disposed=" + _disposed +
               '}';
    }

    @Override
    public final boolean hasRemaining()
    {
        return _buffer.hasRemaining();
    }

    @Override
    public boolean hasRemaining(final int atLeast)
    {
        return _buffer.remaining() >= atLeast;
    }

    @Override
    public SingleQpidByteBuffer putInt(final int index, final int value)
    {
        _buffer.putInt(index, value);
        return this;
    }

    @Override
    public SingleQpidByteBuffer putShort(final int index, final short value)
    {
        _buffer.putShort(index, value);
        return this;
    }

    @Override
    public SingleQpidByteBuffer putChar(final int index, final char value)
    {
        _buffer.putChar(index, value);
        return this;
    }

    @Override
    public final SingleQpidByteBuffer put(final byte b)
    {
        _buffer.put(b);
        return this;
    }

    @Override
    public SingleQpidByteBuffer put(final int index, final byte b)
    {
        _buffer.put(index, b);
        return this;
    }

    @Override
    public short getShort(final int index)
    {
        return _buffer.getShort(index);
    }

    @Override
    public final SingleQpidByteBuffer mark()
    {
        _buffer.mark();
        return this;
    }

    @Override
    public final long getLong()
    {
        return _buffer.getLong();
    }

    @Override
    public SingleQpidByteBuffer putFloat(final int index, final float value)
    {
        _buffer.putFloat(index, value);
        return this;
    }

    @Override
    public double getDouble(final int index)
    {
        return _buffer.getDouble(index);
    }

    @Override
    public final boolean hasArray()
    {
        return _buffer.hasArray();
    }

    @Override
    public final double getDouble()
    {
        return _buffer.getDouble();
    }

    @Override
    public final SingleQpidByteBuffer putFloat(final float value)
    {
        _buffer.putFloat(value);
        return this;
    }

    @Override
    public final SingleQpidByteBuffer putInt(final int value)
    {
        _buffer.putInt(value);
        return this;
    }

    @Override
    public byte[] array()
    {
        return _buffer.array();
    }

    @Override
    public final SingleQpidByteBuffer putShort(final short value)
    {
        _buffer.putShort(value);
        return this;
    }

    @Override
    public int getInt(final int index)
    {
        return _buffer.getInt(index);
    }

    @Override
    public final int remaining()
    {
        return _buffer.remaining();
    }

    @Override
    public final SingleQpidByteBuffer put(final byte[] src)
    {
        _buffer.put(src);
        return this;
    }

    @Override
    public final SingleQpidByteBuffer put(final ByteBuffer src)
    {
        _buffer.put(src);
        return this;
    }

    @Override
    public final SingleQpidByteBuffer put(final QpidByteBuffer src)
    {
        if (src.remaining() > remaining())
        {
            throw new BufferOverflowException();
        }

        if (src instanceof SingleQpidByteBuffer)
        {
            _buffer.put(((SingleQpidByteBuffer) src).getUnderlyingBuffer());
        }
        else if (src instanceof MultiQpidByteBuffer)
        {
            for (final SingleQpidByteBuffer singleQpidByteBuffer : ((MultiQpidByteBuffer) src).getFragments())
            {
                _buffer.put(singleQpidByteBuffer.getUnderlyingBuffer());
            }
        }
        else
        {
            throw new IllegalStateException("unknown QBB implementation");
        }
        return this;
    }

    @Override
    public final SingleQpidByteBuffer get(final byte[] dst, final int offset, final int length)
    {
        _buffer.get(dst, offset, length);
        return this;
    }

    @Override
    public final void copyTo(final ByteBuffer dst)
    {
        dst.put(_buffer.duplicate());
    }

    @Override
    public final void putCopyOf(final QpidByteBuffer source)
    {
        int remaining = remaining();
        int sourceRemaining = source.remaining();
        if (sourceRemaining > remaining)
        {
            throw new BufferOverflowException();
        }

        if (source instanceof SingleQpidByteBuffer)
        {
            put(((SingleQpidByteBuffer) source).getUnderlyingBuffer().duplicate());
        }
        else if (source instanceof MultiQpidByteBuffer)
        {
            for (final SingleQpidByteBuffer singleQpidByteBuffer : ((MultiQpidByteBuffer) source).getFragments())
            {
                put(singleQpidByteBuffer.getUnderlyingBuffer().duplicate());
            }
        }
        else
        {
            throw new IllegalStateException("unknown QBB implementation");
        }
    }

    @Override
    public SingleQpidByteBuffer rewind()
    {
        _buffer.rewind();
        return this;
    }

    @Override
    public SingleQpidByteBuffer clear()
    {
        _buffer.clear();
        return this;
    }

    @Override
    public SingleQpidByteBuffer putLong(final int index, final long value)
    {
        _buffer.putLong(index, value);
        return this;
    }

    @Override
    public SingleQpidByteBuffer compact()
    {
        _buffer.compact();
        return this;
    }

    @Override
    public final SingleQpidByteBuffer putDouble(final double value)
    {
        _buffer.putDouble(value);
        return this;
    }

    @Override
    public int limit()
    {
        return _buffer.limit();
    }

    @Override
    public SingleQpidByteBuffer reset()
    {
        _buffer.reset();
        return this;
    }

    @Override
    public SingleQpidByteBuffer flip()
    {
        _buffer.flip();
        return this;
    }

    @Override
    public final short getShort()
    {
        return _buffer.getShort();
    }

    @Override
    public final float getFloat()
    {
        return _buffer.getFloat();
    }

    @Override
    public SingleQpidByteBuffer limit(final int newLimit)
    {
        _buffer.limit(newLimit);
        return this;
    }

    /**
     * Method does not respect mark.
     *
     * @return SingleQpidByteBuffer
     */
    @Override
    public SingleQpidByteBuffer duplicate()
    {
        ByteBuffer buffer = _ref.getBuffer();
        if (!(_ref instanceof PooledByteBufferRef))
        {
            buffer = buffer.duplicate();
        }

        buffer.position(_offset );
        buffer.limit(_offset + _buffer.capacity());

        buffer = buffer.slice();

        buffer.limit(_buffer.limit());
        buffer.position(_buffer.position());
        return new SingleQpidByteBuffer(_ref, buffer, _offset);
    }

    @Override
    public final SingleQpidByteBuffer put(final byte[] src, final int offset, final int length)
    {
        _buffer.put(src, offset, length);
        return this;
    }

    @Override
    public long getLong(final int index)
    {
        return _buffer.getLong(index);
    }

    @Override
    public int capacity()
    {
        return _buffer.capacity();
    }

    @Override
    public char getChar(final int index)
    {
        return _buffer.getChar(index);
    }

    @Override
    public final byte get()
    {
        return _buffer.get();
    }

    @Override
    public byte get(final int index)
    {
        return _buffer.get(index);
    }

    @Override
    public final SingleQpidByteBuffer get(final byte[] dst)
    {
        _buffer.get(dst);
        return this;
    }

    @Override
    public final void copyTo(final byte[] dst)
    {
        if (remaining() < dst.length)
        {
            throw new BufferUnderflowException();
        }
        _buffer.duplicate().get(dst);
    }

    @Override
    public final SingleQpidByteBuffer putChar(final char value)
    {
        _buffer.putChar(value);
        return this;
    }

    @Override
    public SingleQpidByteBuffer position(final int newPosition)
    {
        _buffer.position(newPosition);
        return this;
    }

    @Override
    public final char getChar()
    {
        return _buffer.getChar();
    }

    @Override
    public final int getInt()
    {
        return _buffer.getInt();
    }

    @Override
    public final SingleQpidByteBuffer putLong(final long value)
    {
        _buffer.putLong(value);
        return this;
    }

    @Override
    public float getFloat(final int index)
    {
        return _buffer.getFloat(index);
    }

    @Override
    public SingleQpidByteBuffer slice()
    {
        return view(0, _buffer.remaining());
    }

    @Override
    public SingleQpidByteBuffer view(int offset, int length)
    {
        ByteBuffer buffer = _ref.getBuffer();
        if (!(_ref instanceof PooledByteBufferRef))
        {
            buffer = buffer.duplicate();
        }

        int newRemaining = Math.min(_buffer.remaining() - offset, length);

        int newPosition = _offset + _buffer.position() + offset;
        buffer.limit(newPosition + newRemaining);
        buffer.position(newPosition);

        buffer = buffer.slice();

        return new SingleQpidByteBuffer(_ref, buffer, newPosition);
    }

    @Override
    public int position()
    {
        return _buffer.position();
    }

    @Override
    public SingleQpidByteBuffer putDouble(final int index, final double value)
    {
        _buffer.putDouble(index, value);
        return this;
    }

    ByteBuffer getUnderlyingBuffer()
    {
        return _buffer;
    }

    @Override
    public boolean isSparse()
    {
        return _ref.isSparse(QpidByteBufferFactory.getSparsityFraction());
    }
}
