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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadLocalRandom;

import org.junit.Assert;
import org.junit.Test;

import org.apache.cassandra.io.compress.BufferType;
import org.apache.cassandra.utils.ByteBufferUtil;

public class DataOutputTest
{
    @Test
    public void testWrappedDataOutputStreamPlus() throws IOException
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStreamPlus write = new WrappedDataOutputStreamPlus(bos);
        DataInput canon = testWrite(write);
        DataInput test = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
        testRead(test, canon);
    }

    @Test
    public void testWrappedDataOutputChannelAndChannel() throws IOException
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStreamPlus write = new WrappedDataOutputStreamPlus(bos);
        DataInput canon = testWrite(write);
        DataInput test = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
        testRead(test, canon);
    }

    @Test
    public void testBufferedDataOutputStreamPlusAndChannel() throws IOException
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStreamPlus write = new BufferedDataOutputStreamPlus(Channels.newChannel(bos));
        DataInput canon = testWrite(write);
        write.close();
        DataInput test = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
        testRead(test, canon);
    }

    @Test
    public void testDataOutputBuffer() throws IOException
    {
        DataOutputBuffer write = new DataOutputBuffer();
        DataInput canon = testWrite(write);
        DataInput test = new DataInputStream(new ByteArrayInputStream(write.toByteArray()));
        testRead(test, canon);
    }

    @Test
    public void testDataOutputBufferZeroReallocate() throws IOException
    {
        try (DataOutputBufferSpy write = new DataOutputBufferSpy())
        {
            for (int ii = 0; ii < 1000000; ii++)
            {
                write.superReallocate(0);
            }
        }
    }

    @Test
    public void testDataOutputDirectByteBuffer() throws IOException
    {
        ByteBuffer buf = wrap(new byte[345], true);
        BufferedDataOutputStreamPlus write = new BufferedDataOutputStreamPlus(null, buf.duplicate());
        DataInput canon = testWrite(write);
        DataInput test = new DataInputStream(new ByteArrayInputStream(ByteBufferUtil.getArray(buf)));
        testRead(test, canon);
    }

    @Test
    public void testDataOutputHeapByteBuffer() throws IOException
    {
        ByteBuffer buf = wrap(new byte[345], false);
        BufferedDataOutputStreamPlus write = new BufferedDataOutputStreamPlus(null, buf.duplicate());
        DataInput canon = testWrite(write);
        DataInput test = new DataInputStream(new ByteArrayInputStream(ByteBufferUtil.getArray(buf)));
        testRead(test, canon);
    }

    private static class DataOutputBufferSpy extends DataOutputBuffer
    {
        Deque<Long> sizes = new ArrayDeque<>();

        DataOutputBufferSpy()
        {
            sizes.offer(128L);
        }

        void publicFlush() throws IOException
        {
            //Going to allow it to double instead of specifying a count
            doFlush(1);
        }

        void superReallocate(int count) throws IOException
        {
            super.reallocate(count);
        }

        @Override
        protected void reallocate(long count)
        {
            if (count <= 0)
                return;
            Long lastSize = sizes.peekLast();
            long newSize = calculateNewSize(count);
            sizes.offer(newSize);
            if (newSize > DataOutputBuffer.MAX_ARRAY_SIZE)
                throw new RuntimeException();
            if (newSize < 0)
                throw new AssertionError();
            if (lastSize != null && newSize <= lastSize)
                throw new AssertionError();
        }

        @Override
        protected long capacity()
        {
            return sizes.peekLast().intValue();
        }
    }

    //Check for overflow at the max size, without actually allocating all the memory
    @Test
    public void testDataOutputBufferMaxSizeFake() throws IOException
    {
        try (DataOutputBufferSpy write = new DataOutputBufferSpy())
        {
            boolean threw = false;
            try
            {
                while (true)
                    write.publicFlush();
            }
            catch (RuntimeException e) {
                if (e.getClass() == RuntimeException.class)
                    threw = true;
            }
            Assert.assertTrue(threw);
            Assert.assertTrue(write.sizes.peekLast() >= DataOutputBuffer.MAX_ARRAY_SIZE);
        }
    }

    @Test
    public void testDataOutputBufferMaxSize() throws IOException
    {
        //Need a lot of heap to run this test for real.
        //Tested everything else as much as possible since we can't do it all the time
        if (Runtime.getRuntime().maxMemory() < 5033164800L)
            return;

        try (DataOutputBuffer write = new DataOutputBuffer())
        {
            //Doesn't throw up to DataOuptutBuffer.MAX_ARRAY_SIZE which is the array size limit in Java
            for (int ii = 0; ii < DataOutputBuffer.MAX_ARRAY_SIZE / 8; ii++)
                write.writeLong(0);
            write.write(new byte[7]);

            //Should fail due to validation
            checkThrowsRuntimeException(validateReallocationCallable( write, DataOutputBuffer.MAX_ARRAY_SIZE + 1));
            //Check that it does throw
            checkThrowsRuntimeException(new Callable<Object>()
            {
                public Object call() throws Exception
                {
                    write.write(42);
                    return null;
                }
            });
        }
    }

    //Can't test it for real without tons of heap so test as much validation as possible
    @Test
    public void testDataOutputBufferBigReallocation() throws Exception
    {
        //Check saturating cast behavior
        Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE, DataOutputBuffer.saturatedArraySizeCast(DataOutputBuffer.MAX_ARRAY_SIZE + 1L));
        Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE, DataOutputBuffer.saturatedArraySizeCast(DataOutputBuffer.MAX_ARRAY_SIZE));
        Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE - 1, DataOutputBuffer.saturatedArraySizeCast(DataOutputBuffer.MAX_ARRAY_SIZE - 1));
        Assert.assertEquals(0, DataOutputBuffer.saturatedArraySizeCast(0));
        Assert.assertEquals(1, DataOutputBuffer.saturatedArraySizeCast(1));
        checkThrowsIAE(saturatedArraySizeCastCallable(-1));

        //Check checked cast behavior
        checkThrowsIAE(checkedArraySizeCastCallable(DataOutputBuffer.MAX_ARRAY_SIZE + 1L));
        Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE, DataOutputBuffer.checkedArraySizeCast(DataOutputBuffer.MAX_ARRAY_SIZE));
        Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE - 1, DataOutputBuffer.checkedArraySizeCast(DataOutputBuffer.MAX_ARRAY_SIZE - 1));
        Assert.assertEquals(0, DataOutputBuffer.checkedArraySizeCast(0));
        Assert.assertEquals(1, DataOutputBuffer.checkedArraySizeCast(1));
        checkThrowsIAE(checkedArraySizeCastCallable(-1));


        try (DataOutputBuffer write = new DataOutputBuffer())
        {
            //Checked validation performed by DOB
            Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE, write.validateReallocation(DataOutputBuffer.MAX_ARRAY_SIZE + 1L));
            Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE, write.validateReallocation(DataOutputBuffer.MAX_ARRAY_SIZE));
            Assert.assertEquals(DataOutputBuffer.MAX_ARRAY_SIZE - 1, write.validateReallocation(DataOutputBuffer.MAX_ARRAY_SIZE - 1));
            checkThrowsRuntimeException(validateReallocationCallable( write, 0));
            checkThrowsRuntimeException(validateReallocationCallable( write, 1));
            checkThrowsIAE(validateReallocationCallable( write, -1));
        }
    }

    Callable<Object> saturatedArraySizeCastCallable(final long value)
    {
        return new Callable<Object>()
        {
            @Override
            public Object call() throws Exception
            {
                return DataOutputBuffer.saturatedArraySizeCast(value);
            }
        };
    }

    Callable<Object> checkedArraySizeCastCallable(final long value)
    {
        return new Callable<Object>()
        {
            @Override
            public Object call() throws Exception
            {
                return DataOutputBuffer.checkedArraySizeCast(value);
            }
        };
    }

    Callable<Object> validateReallocationCallable(final DataOutputBuffer write, final long value)
    {
        return new Callable<Object>()
        {
            @Override
            public Object call() throws Exception
            {
                return write.validateReallocation(value);
            }
        };
    }

    private static void checkThrowsIAE(Callable<Object> c)
    {
        checkThrowsException(c, IllegalArgumentException.class);
    }

    private static void checkThrowsRuntimeException(Callable<Object> c)
    {
        checkThrowsException(c, RuntimeException.class);
    }

    private static void checkThrowsException(Callable<Object> c, Class<?> exceptionClass)
    {
        boolean threw = false;
        try
        {
            c.call();
        }
        catch (Throwable t)
        {
            if (t.getClass() == exceptionClass)
                threw = true;
        }
        Assert.assertTrue(threw);
    }

    @Test
    public void testSafeMemoryWriter() throws IOException
    {
        try (SafeMemoryWriter write = new SafeMemoryWriter(10))
        {
            DataInput canon = testWrite(write);
            byte[] bytes = new byte[345];
            write.currentBuffer().getBytes(0, bytes, 0, 345);
            DataInput test = new DataInputStream(new ByteArrayInputStream(bytes));
            testRead(test, canon);
        }
    }

    @Test
    public void testWrappedFileOutputStream() throws IOException
    {
        File file = FileUtils.createTempFile("dataoutput", "test");
        try
        {
            DataOutputStreamPlus write = new WrappedDataOutputStreamPlus(new FileOutputStream(file));
            DataInput canon = testWrite(write);
            write.close();
            DataInputStream test = new DataInputStream(new FileInputStream(file));
            testRead(test, canon);
            test.close();
        }
        finally
        {
            Assert.assertTrue(file.delete());
        }
    }

    @Test
    public void testFileOutputStream() throws IOException
    {
        File file = FileUtils.createTempFile("dataoutput", "test");
        try
        {
            DataOutputStreamPlus write = new BufferedDataOutputStreamPlus(new FileOutputStream(file));
            DataInput canon = testWrite(write);
            write.close();
            DataInputStream test = new DataInputStream(new FileInputStream(file));
            testRead(test, canon);
            test.close();
        }
        finally
        {
            Assert.assertTrue(file.delete());
        }
    }

    @Test
    public void testRandomAccessFile() throws IOException
    {
        File file = FileUtils.createTempFile("dataoutput", "test");
        try
        {
            @SuppressWarnings("resource")
            final RandomAccessFile raf = new RandomAccessFile(file, "rw");
            DataOutputStreamPlus write = new BufferedDataOutputStreamPlus(raf.getChannel());
            DataInput canon = testWrite(write);
            write.close();
            DataInputStream test = new DataInputStream(new FileInputStream(file));
            testRead(test, canon);
            test.close();
        }
        finally
        {
            Assert.assertTrue(file.delete());
        }
    }

    @Test
    public void testSequentialWriter() throws IOException
    {
        File file = FileUtils.createTempFile("dataoutput", "test");
        final SequentialWriter writer = new SequentialWriter(file, 32, BufferType.ON_HEAP);
        DataOutputStreamPlus write = new WrappedDataOutputStreamPlus(writer.finishOnClose());
        DataInput canon = testWrite(write);
        write.flush();
        write.close();
        DataInputStream test = new DataInputStream(new FileInputStream(file));
        testRead(test, canon);
        test.close();
        Assert.assertTrue(file.delete());
    }

    private DataInput testWrite(DataOutputPlus test) throws IOException
    {
        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
        final DataOutput canon = new DataOutputStream(bos);
        Random rnd = ThreadLocalRandom.current();

        int size = 50;
        byte[] bytes = new byte[size];
        rnd.nextBytes(bytes);
        ByteBufferUtil.writeWithLength(bytes, test);
        ByteBufferUtil.writeWithLength(bytes, canon);

        bytes = new byte[size];
        rnd.nextBytes(bytes);
        ByteBufferUtil.writeWithLength(wrap(bytes, false), test);
        ByteBufferUtil.writeWithLength(bytes, canon);

        bytes = new byte[size];
        rnd.nextBytes(bytes);
        ByteBufferUtil.writeWithLength(wrap(bytes, true), test);
        ByteBufferUtil.writeWithLength(bytes, canon);

        bytes = new byte[size];
        rnd.nextBytes(bytes);
        ByteBufferUtil.writeWithShortLength(bytes, test);
        ByteBufferUtil.writeWithShortLength(bytes, canon);

        bytes = new byte[size];
        rnd.nextBytes(bytes);
        ByteBufferUtil.writeWithShortLength(wrap(bytes, false), test);
        ByteBufferUtil.writeWithShortLength(bytes, canon);

        bytes = new byte[size];
        rnd.nextBytes(bytes);
        ByteBufferUtil.writeWithShortLength(wrap(bytes, true), test);
        ByteBufferUtil.writeWithShortLength(bytes, canon);
        // 318

        {
            long v = rnd.nextLong();
            test.writeLong(v);
            canon.writeLong(v);
        }
        {
            int v = rnd.nextInt();
            test.writeInt(v);
            canon.writeInt(v);
        }
        {
            short v = (short) rnd.nextInt();
            test.writeShort(v);
            canon.writeShort(v);
        }
        {
            byte v = (byte) rnd.nextInt();
            test.write(v);
            canon.write(v);
        }
        {
            double v = rnd.nextDouble();
            test.writeDouble(v);
            canon.writeDouble(v);
        }
        {
            float v = (float) rnd.nextDouble();
            test.writeFloat(v);
            canon.writeFloat(v);
        }

        // 27
        return new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
    }

    private void testRead(DataInput test, DataInput canon) throws IOException
    {
        Assert.assertEquals(ByteBufferUtil.readWithLength(canon), ByteBufferUtil.readWithLength(test));
        Assert.assertEquals(ByteBufferUtil.readWithLength(canon), ByteBufferUtil.readWithLength(test));
        Assert.assertEquals(ByteBufferUtil.readWithLength(canon), ByteBufferUtil.readWithLength(test));
        Assert.assertEquals(ByteBufferUtil.readWithShortLength(canon), ByteBufferUtil.readWithShortLength(test));
        Assert.assertEquals(ByteBufferUtil.readWithShortLength(canon), ByteBufferUtil.readWithShortLength(test));
        Assert.assertEquals(ByteBufferUtil.readWithShortLength(canon), ByteBufferUtil.readWithShortLength(test));
        assert test.readLong() == canon.readLong();
        assert test.readInt() == canon.readInt();
        assert test.readShort() == canon.readShort();
        assert test.readByte() == canon.readByte();
        assert test.readDouble() == canon.readDouble();
        assert test.readFloat() == canon.readFloat();
        try
        {
            test.readInt();
            assert false;
        }
        catch (EOFException ignore)
        {
            // it worked
        }
    }

    private static ByteBuffer wrap(byte[] bytes, boolean direct)
    {
        ByteBuffer buf = direct ? ByteBuffer.allocateDirect(bytes.length + 20) : ByteBuffer.allocate(bytes.length + 20);
        buf.position(10);
        buf.limit(bytes.length + 10);
        buf.duplicate().put(bytes);
        return buf;
    }
}
