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

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.zip.CRC32;

import org.junit.BeforeClass;
import org.junit.Test;

import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.io.util.DataOutputBuffer;
import org.apache.cassandra.io.util.RandomAccessReader;
import org.apache.cassandra.io.util.SequentialWriter;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertFalse;

public class ChecksummedDataInputTest
{
    @BeforeClass
    public static void setupDD()
    {
        DatabaseDescriptor.daemonInitialization();
    }

    @Test
    public void testReadMethods() throws IOException
    {
        // Make sure this array is bigger than the reader buffer size
        // so we test updating the crc across buffer boundaries
        byte[] b = new byte[RandomAccessReader.DEFAULT_BUFFER_SIZE * 2];
        for (int i = 0; i < b.length; i++)
            b[i] = (byte)i;

        ByteBuffer buffer;

        // fill a bytebuffer with some input
        try (DataOutputBuffer out = new DataOutputBuffer())
        {
            out.write(127);
            out.write(b);
            out.writeBoolean(false);
            out.writeByte(10);
            out.writeChar('t');
            out.writeDouble(3.3);
            out.writeFloat(2.2f);
            out.writeInt(42);
            out.writeLong(Long.MAX_VALUE);
            out.writeShort(Short.MIN_VALUE);
            out.writeUTF("utf");
            out.writeVInt(67L);
            out.writeUnsignedVInt(88L);
            out.writeBytes("abcdefghi");

            buffer = out.buffer();
        }

        // calculate expected CRC
        CRC32 crc = new CRC32();
        FBUtilities.updateChecksum(crc, buffer);

        // save the buffer to file to create a RAR
        File file = File.createTempFile("testReadMethods", "1");
        file.deleteOnExit();
        try (SequentialWriter writer = new SequentialWriter(file))
        {
            writer.write(buffer);
            writer.writeInt((int) crc.getValue());
            writer.finish();
        }

        assertTrue(file.exists());
        assertEquals(buffer.remaining() + 4, file.length());

        try (ChecksummedDataInput reader = ChecksummedDataInput.open(file))
        {
            reader.limit(buffer.remaining() + 4);

            // assert that we read all the right values back
            assertEquals(127, reader.read());
            byte[] bytes = new byte[b.length];
            reader.readFully(bytes);
            assertTrue(Arrays.equals(bytes, b));
            assertEquals(false, reader.readBoolean());
            assertEquals(10, reader.readByte());
            assertEquals('t', reader.readChar());
            assertEquals(3.3, reader.readDouble());
            assertEquals(2.2f, reader.readFloat());
            assertEquals(42, reader.readInt());
            assertEquals(Long.MAX_VALUE, reader.readLong());
            assertEquals(Short.MIN_VALUE, reader.readShort());
            assertEquals("utf", reader.readUTF());
            assertEquals(67L, reader.readVInt());
            assertEquals(88L, reader.readUnsignedVInt());
            assertEquals("abcdefghi", new String(ByteBufferUtil.read(reader, 9).array(), StandardCharsets.UTF_8));

            // assert that the crc matches, and that we've read exactly as many bytes as expected
            assertTrue(reader.checkCrc());
            assertTrue(reader.isEOF());

            reader.checkLimit(0);
        }
    }

    @Test
    public void testResetCrc() throws IOException
    {
        CRC32 crc = new CRC32();
        ByteBuffer buffer;

        // fill a bytebuffer with some input
        try (DataOutputBuffer out = new DataOutputBuffer())
        {
            out.write(127);
            out.writeBoolean(false);
            out.writeByte(10);
            out.writeChar('t');

            buffer = out.buffer();
            FBUtilities.updateChecksum(crc, buffer);
            out.writeInt((int) crc.getValue());

            int bufferPos = out.getLength();
            out.writeDouble(3.3);
            out.writeFloat(2.2f);
            out.writeInt(42);

            buffer = out.buffer();
            buffer.position(bufferPos);
            crc.reset();
            FBUtilities.updateChecksum(crc, buffer);

            out.writeInt((int) crc.getValue());
            buffer = out.buffer();
        }

        // save the buffer to file to create a RAR
        File file = File.createTempFile("testResetCrc", "1");
        file.deleteOnExit();
        try (SequentialWriter writer = new SequentialWriter(file))
        {
            writer.write(buffer);
            writer.finish();
        }

        assertTrue(file.exists());
        assertEquals(buffer.remaining(), file.length());

        try (ChecksummedDataInput reader = ChecksummedDataInput.open(file))
        {
            reader.limit(buffer.remaining());

            // assert that we read all the right values back
            assertEquals(127, reader.read());
            assertEquals(false, reader.readBoolean());
            assertEquals(10, reader.readByte());
            assertEquals('t', reader.readChar());
            assertTrue(reader.checkCrc());

            reader.resetCrc();
            assertEquals(3.3, reader.readDouble());
            assertEquals(2.2f, reader.readFloat());
            assertEquals(42, reader.readInt());
            assertTrue(reader.checkCrc());
            assertTrue(reader.isEOF());
        }
    }

    @Test
    public void testFailedCrc() throws IOException
    {
        CRC32 crc = new CRC32();
        ByteBuffer buffer;

        // fill a bytebuffer with some input
        try (DataOutputBuffer out = new DataOutputBuffer())
        {
            out.write(127);
            out.writeBoolean(false);
            out.writeByte(10);
            out.writeChar('t');

            buffer = out.buffer();
            FBUtilities.updateChecksum(crc, buffer);

            // update twice so it won't match
            FBUtilities.updateChecksum(crc, buffer);
            out.writeInt((int) crc.getValue());

            buffer = out.buffer();
        }

        // save the buffer to file to create a RAR
        File file = File.createTempFile("testFailedCrc", "1");
        file.deleteOnExit();
        try (SequentialWriter writer = new SequentialWriter(file))
        {
            writer.write(buffer);
            writer.finish();
        }

        assertTrue(file.exists());
        assertEquals(buffer.remaining(), file.length());

        try (ChecksummedDataInput reader = ChecksummedDataInput.open(file))
        {
            reader.limit(buffer.remaining());

            // assert that we read all the right values back
            assertEquals(127, reader.read());
            assertEquals(false, reader.readBoolean());
            assertEquals(10, reader.readByte());
            assertEquals('t', reader.readChar());
            assertFalse(reader.checkCrc());
            assertTrue(reader.isEOF());
        }
    }
}
