/*
 *
 * 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.util;

import org.apache.qpid.test.utils.QpidTestCase;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;

public class ByteBufferInputStreamTest extends QpidTestCase
{
    private byte[] _data = {2, 1, 5, 3, 4};
    private ByteBufferInputStream _inputStream;

    public void setUp() throws Exception
    {
        super.setUp();
        _inputStream = new ByteBufferInputStream(ByteBuffer.wrap(_data));
    }

    public void testRead() throws IOException
    {
        for (int i = 0; i < _data.length; i++)
        {
            assertEquals("Unexpected byte at position " + i, _data[i], _inputStream.read());
        }
        assertEquals("EOF not reached", -1, _inputStream.read());
    }

    public void testReadByteArray() throws IOException
    {
        byte[] readBytes = new byte[_data.length];
        int length = _inputStream.read(readBytes, 0, 2);

        byte[] expected = new byte[_data.length];
        System.arraycopy(_data, 0, expected, 0, 2);

        assertTrue("Unexpected data", Arrays.equals(expected, readBytes));
        assertEquals("Unexpected length", 2, length);

        length = _inputStream.read(readBytes, 2, 3);

        assertTrue("Unexpected data", Arrays.equals(_data, readBytes));
        assertEquals("Unexpected length", 3, length);

        length = _inputStream.read(readBytes);
        assertEquals("EOF not reached", -1, length);
    }

    public void testSkip() throws IOException
    {
        _inputStream.skip(3);
        byte[] readBytes = new byte[_data.length - 3];
        int length = _inputStream.read(readBytes);

        byte[] expected = new byte[_data.length - 3];
        System.arraycopy(_data, 3, expected, 0, _data.length - 3);

        assertTrue("Unexpected data", Arrays.equals(expected, readBytes));
        assertEquals("Unexpected length", _data.length - 3, length);
    }

    public void testAvailable() throws IOException
    {
        int available = _inputStream.available();
        assertEquals("Unexpected number of available bytes", _data.length, available);
        byte[] readBytes = new byte[_data.length];
        _inputStream.read(readBytes);
        available = _inputStream.available();
        assertEquals("Unexpected number of available bytes", 0, available);
    }

    public void testMarkReset() throws IOException
    {
        _inputStream.mark(0);
        byte[] readBytes = new byte[_data.length];
        int length = _inputStream.read(readBytes);
        assertEquals("Unexpected length", _data.length, length);
        assertEquals("Unexpected number of available bytes", 0, _inputStream.available());

        _inputStream.reset();
        readBytes = new byte[_data.length];
        length = _inputStream.read(readBytes);
        assertEquals("Unexpected length", _data.length, length);
        assertEquals("Unexpected number of available bytes", 0, _inputStream.available());
    }

    public void testMarkSupported() throws IOException
    {
        assertTrue("Unexpected mark supported", _inputStream.markSupported());
    }

}
