/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed 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 com.android.apksig.internal.util;

import com.android.apksig.util.DataSink;
import com.android.apksig.util.DataSource;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * {@link DataSource} backed by a {@link FileChannel} for {@link RandomAccessFile} access.
 */
public class RandomAccessFileDataSource implements DataSource {

    private static final int MAX_READ_CHUNK_SIZE = 1024 * 1024;

    private final FileChannel mChannel;
    private final long mOffset;
    private final long mSize;

    /**
     * Constructs a new {@code RandomAccessFileDataSource} based on the data contained in the
     * whole file. Changes to the contents of the file, including the size of the file,
     * will be visible in this data source.
     */
    public RandomAccessFileDataSource(RandomAccessFile file) {
        mChannel = file.getChannel();
        mOffset = 0;
        mSize = -1;
    }

    /**
     * Constructs a new {@code RandomAccessFileDataSource} based on the data contained in the
     * specified region of the provided file. Changes to the contents of the file will be visible in
     * this data source.
     *
     * @throws IndexOutOfBoundsException if {@code offset} or {@code size} is negative.
     */
    public RandomAccessFileDataSource(RandomAccessFile file, long offset, long size) {
        this(file.getChannel(), offset, size);
    }

    private RandomAccessFileDataSource(FileChannel channel, long offset, long size) {
        if (offset < 0) {
            throw new IndexOutOfBoundsException("offset: " + size);
        }
        if (size < 0) {
            throw new IndexOutOfBoundsException("size: " + size);
        }
        mChannel = channel;
        mOffset = offset;
        mSize = size;
    }

    @Override
    public long size() {
        if (mSize == -1) {
            try {
                return mChannel.size();
            } catch (IOException e) {
                return 0;
            }
        } else {
            return mSize;
        }
    }

    @Override
    public RandomAccessFileDataSource slice(long offset, long size) {
        long sourceSize = size();
        checkChunkValid(offset, size, sourceSize);
        if ((offset == 0) && (size == sourceSize)) {
            return this;
        }

        return new RandomAccessFileDataSource(mChannel, mOffset + offset, size);
    }

    @Override
    public void feed(long offset, long size, DataSink sink) throws IOException {
        long sourceSize = size();
        checkChunkValid(offset, size, sourceSize);
        if (size == 0) {
            return;
        }

        long chunkOffsetInFile = mOffset + offset;
        long remaining = size;
        ByteBuffer buf = ByteBuffer.allocateDirect((int) Math.min(remaining, MAX_READ_CHUNK_SIZE));

        while (remaining > 0) {
            int chunkSize = (int) Math.min(remaining, buf.capacity());
            int chunkRemaining = chunkSize;
            buf.limit(chunkSize);
            synchronized (mChannel) {
                mChannel.position(chunkOffsetInFile);
                while (chunkRemaining > 0) {
                    int read = mChannel.read(buf);
                    if (read < 0) {
                        throw new IOException("Unexpected EOF encountered");
                    }
                    chunkRemaining -= read;
                }
            }
            buf.flip();
            sink.consume(buf);
            buf.clear();
            chunkOffsetInFile += chunkSize;
            remaining -= chunkSize;
        }
    }

    @Override
    public void copyTo(long offset, int size, ByteBuffer dest) throws IOException {
        long sourceSize = size();
        checkChunkValid(offset, size, sourceSize);
        if (size == 0) {
            return;
        }
        if (size > dest.remaining()) {
            throw new BufferOverflowException();
        }

        long offsetInFile = mOffset + offset;
        int remaining = size;
        int prevLimit = dest.limit();
        try {
            // FileChannel.read(ByteBuffer) reads up to dest.remaining(). Thus, we need to adjust
            // the buffer's limit to avoid reading more than size bytes.
            dest.limit(dest.position() + size);
            while (remaining > 0) {
                int chunkSize;
                synchronized (mChannel) {
                    mChannel.position(offsetInFile);
                    chunkSize = mChannel.read(dest);
                }
                offsetInFile += chunkSize;
                remaining -= chunkSize;
            }
        } finally {
            dest.limit(prevLimit);
        }
    }

    @Override
    public ByteBuffer getByteBuffer(long offset, int size) throws IOException {
        if (size < 0) {
            throw new IndexOutOfBoundsException("size: " + size);
        }
        ByteBuffer result = ByteBuffer.allocate(size);
        copyTo(offset, size, result);
        result.flip();
        return result;
    }

    private static void checkChunkValid(long offset, long size, long sourceSize) {
        if (offset < 0) {
            throw new IndexOutOfBoundsException("offset: " + offset);
        }
        if (size < 0) {
            throw new IndexOutOfBoundsException("size: " + size);
        }
        if (offset > sourceSize) {
            throw new IndexOutOfBoundsException(
                    "offset (" + offset + ") > source size (" + sourceSize + ")");
        }
        long endOffset = offset + size;
        if (endOffset < offset) {
            throw new IndexOutOfBoundsException(
                    "offset (" + offset + ") + size (" + size + ") overflow");
        }
        if (endOffset > sourceSize) {
            throw new IndexOutOfBoundsException(
                    "offset (" + offset + ") + size (" + size
                            + ") > source size (" + sourceSize  +")");
        }
    }
}
