package com.jscape.inet.ssh.protocol.v2.connection;

import com.jscape.util.ArrayTools;

import java.util.LinkedList;
import java.util.List;

/**
 * @author Alex Usun
 */
public class ReadingBuffer {

    private final List<byte[]> blocks;
    private int currentPosition;
    private volatile int available;
    private volatile boolean closed;

    public ReadingBuffer() {
        this.blocks = new LinkedList<>();
    }

    public int available() {
        return this.available;
    }

    public boolean empty() {
        return this.available == 0;
    }

    public void put(byte[] data) {
        if (data.length == 0) {
            return;
        }

        this.blocks.add(data);
        this.available += data.length;
    }

    public int read(byte[] buffer, int offset, int length) {
        if (empty()) {
            return this.closed ? -1 : 0;
        }

        byte[] currentBlock = currentBlock();
        int read = Math.min(currentBlock.length - this.currentPosition, length);
        ArrayTools.copy(currentBlock, this.currentPosition, buffer, offset, read);
        this.currentPosition += read;
        this.available -= read;

        return read;
    }

    public void close() {
        this.closed = true;
    }

    public boolean closed() {
        return this.closed;
    }

    @Override
    public String toString() {
        return "ReadingBuffer {"
                + "blocks=" + this.blocks
                + ", currentPosition=" + this.currentPosition
                + ", available=" + this.available
                + '}';
    }

    private byte[] currentBlock() {
        byte[] block = this.blocks.get(0);

        if (this.currentPosition < block.length) {
            return block;
        }

        this.blocks.remove(0);
        this.currentPosition = 0;

        return this.blocks.get(0);
    }

}
