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

import com.google.common.base.Preconditions;

import org.apache.cassandra.io.compress.BufferType;
import org.apache.cassandra.io.util.*;
import org.apache.cassandra.utils.memory.BufferPool;

/**
 * A {@link RandomAccessReader} wrapper that calctulates the CRC in place.
 *
 * Useful for {@link org.apache.cassandra.hints.HintsReader}, for example, where we must verify the CRC, yet don't want
 * to allocate an extra byte array just that purpose. The CRC can be embedded in the input stream and checked via checkCrc().
 *
 * In addition to calculating the CRC, it allows to enforce a maximim known size. This is needed
 * so that {@link org.apache.cassandra.db.Mutation.MutationSerializer} doesn't blow up the heap when deserializing a
 * corrupted sequence by reading a huge corrupted length of bytes via
 * via {@link org.apache.cassandra.utils.ByteBufferUtil#readWithLength(java.io.DataInput)}.
 */
public class ChecksummedDataInput extends RebufferingInputStream
{
    private final CRC32 crc;
    private int crcPosition;
    private boolean crcUpdateDisabled;

    private long limit;
    private long limitMark;

    protected long bufferOffset;
    protected final ChannelProxy channel;

    ChecksummedDataInput(ChannelProxy channel, BufferType bufferType)
    {
        super(BufferPool.get(RandomAccessReader.DEFAULT_BUFFER_SIZE, bufferType));

        crc = new CRC32();
        crcPosition = 0;
        crcUpdateDisabled = false;
        this.channel = channel;
        bufferOffset = 0;
        buffer.limit(0);

        resetLimit();
    }

    ChecksummedDataInput(ChannelProxy channel)
    {
        this(channel, BufferType.OFF_HEAP);
    }

    @SuppressWarnings("resource")
    public static ChecksummedDataInput open(File file)
    {
        return new ChecksummedDataInput(new ChannelProxy(file));
    }

    public boolean isEOF()
    {
        return getPosition() == channel.size();
    }

    /**
     * Returns the position in the source file, which is different for getPosition() for compressed/encrypted files
     * and may be imprecise.
     */
    public long getSourcePosition()
    {
        return getPosition();
    }

    public void resetCrc()
    {
        crc.reset();
        crcPosition = buffer.position();
    }

    public void limit(long newLimit)
    {
        limitMark = getPosition();
        limit = limitMark + newLimit;
    }

    /**
     * Returns the exact position in the uncompressed view of the file.
     */
    protected long getPosition()
    {
        return bufferOffset + buffer.position();
    }

    public void resetLimit()
    {
        limit = Long.MAX_VALUE;
        limitMark = -1;
    }

    public void checkLimit(int length) throws IOException
    {
        if (getPosition() + length > limit)
            throw new IOException("Digest mismatch exception");
    }

    public long bytesPastLimit()
    {
        assert limitMark != -1;
        return getPosition() - limitMark;
    }

    public boolean checkCrc() throws IOException
    {
        try
        {
            updateCrc();

            // we must diable crc updates in case we rebuffer
            // when called source.readInt()
            crcUpdateDisabled = true;
            return ((int) crc.getValue()) == readInt();
        }
        finally
        {
            crcPosition = buffer.position();
            crcUpdateDisabled = false;
        }
    }

    @Override
    public void readFully(byte[] b) throws IOException
    {
        checkLimit(b.length);
        super.readFully(b);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException
    {
        checkLimit(len);
        return super.read(b, off, len);
    }

    @Override
    protected void reBuffer()
    {
        Preconditions.checkState(buffer.remaining() == 0);
        updateCrc();
        bufferOffset += buffer.limit();

        readBuffer();

        crcPosition = buffer.position();
    }

    protected void readBuffer()
    {
        buffer.clear();
        while ((channel.read(buffer, bufferOffset)) == 0) {}
        buffer.flip();
    }

    private void updateCrc()
    {
        if (crcPosition == buffer.position() || crcUpdateDisabled)
            return;

        assert crcPosition >= 0 && crcPosition < buffer.position();

        ByteBuffer unprocessed = buffer.duplicate();
        unprocessed.position(crcPosition)
                   .limit(buffer.position());

        crc.update(unprocessed);
    }

    @Override
    public void close()
    {
        BufferPool.put(buffer);
        channel.close();
    }

    protected String getPath()
    {
        return channel.filePath();
    }

    public ChannelProxy getChannel()
    {
        return channel;
    }
}
