package com.atlassian.stash.internal.plugin.readme;

import java.io.ByteArrayOutputStream;

import static java.lang.String.format;

/**
 * Ensures that the size of the internal byte array never exceeds a given max limit.
 * At the point in which it does, throw a {@link MaxBytesExceededException}.
 */
public class MaxSizeByteArrayOutputStream extends ByteArrayOutputStream {

    private final int maxSize;

    public MaxSizeByteArrayOutputStream(int initialSize, int maxSize) {
        super(initialSize);
        this.maxSize = maxSize;
    }

    private void validate(int length) {
        int newLength = count + length;
        if (newLength > maxSize) {
            throw new MaxBytesExceededException(maxSize, newLength);
        }
    }

    @Override
    public synchronized void write(int b) {
        validate(1);
        super.write(b);
    }

    @Override
    public synchronized void write(byte[] b, int off, int len) {
        validate(len);
        super.write(b, off, len);
    }

    public static class MaxBytesExceededException extends RuntimeException {

        // TODO i18n?
        public MaxBytesExceededException(int maxSize, int length) {
            super(format("Maximum size %s of stream exceeded %s", maxSize, length));
        }
    }
}