import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;

public final class CpioZeroNameSizeByteArrayRuntime {
    private static final byte[] HEADER = (
            "070701" +
            "00000000" +
            "000081A4" +
            "00000000" +
            "00000000" +
            "00000001" +
            "00000000" +
            "00000000" +
            "00000000" +
            "00000000" +
            "00000000" +
            "00000000" +
            "00000000" +
            "00000000"
    ).getBytes(StandardCharsets.US_ASCII);

    private static byte[] payload(final int trailingBytes) {
        final byte[] data = Arrays.copyOf(HEADER, HEADER.length + trailingBytes);
        Arrays.fill(data, HEADER.length, data.length, (byte) 'A');
        return data;
    }

    public static void main(final String[] args) throws Exception {
        final int trailingBytes = args.length == 0 ? 1024 * 1024 : Integer.parseInt(args[0]);
        final ByteArrayInputStream source = new ByteArrayInputStream(payload(trailingBytes));
        final long beforeUsed = usedMemory();
        String outcome = "completed without exception";
        try (CpioArchiveInputStream in = new CpioArchiveInputStream(source)) {
            in.getNextEntry();
        } catch (final EOFException e) {
            outcome = e.getClass().getName() + ": " + e.getMessage();
        } catch (final IOException e) {
            outcome = e.getClass().getName() + ": " + e.getMessage();
        }
        final long afterUsed = usedMemory();
        System.out.println("runtime=" + System.getProperty("java.version") + " " + System.getProperty("java.vm.name"));
        System.out.println("trailingBytes=" + trailingBytes);
        System.out.println("headerBytes=" + HEADER.length);
        System.out.println("outcome=" + outcome);
        System.out.println("byteArrayInputStream.available=" + source.available());
        System.out.println("byteArrayInputStream.consumed=" + (HEADER.length + trailingBytes - source.available()));
        System.out.println("usedMemoryDeltaApprox=" + (afterUsed - beforeUsed));
    }

    private static long usedMemory() {
        final Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
}
