/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.sdm.infrastructure;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * Implementation of {@link InputStream} which combines a given sequence of
 * {@link InputStream} to a single on.
 * <p>
 * Implementation has the following features:
 * <ul>
 * <li>Method {@link #close()} closes all combined streams.</li>
 * <li>Method {@link #available()} always returns {@ code 0}.</li>
 * <li>Marks are not supported.</li>
 * </ul>
 */
public final class CompositeInputStream extends InputStream {
    private final InputStream[] parts;

    private int index;

    /**
     * Constructor
     *
     * @param parts
     *            the parts.
     */
    public CompositeInputStream(final InputStream... parts) {
        this.parts = parts;
    }

    /**
     * Constructor.
     *
     * @param parts
     *            the parts.
     */
    public CompositeInputStream(final List<InputStream> parts) {
        this.parts = parts.toArray(new InputStream[parts.size()]);
    }

    @Override
    public int read() throws IOException {
        int b = -1;
        while (b == -1 && index < parts.length) {
            b = parts[index].read();
            if (b == -1) {
                index++;
            }
        }
        return b;
    }

    @Override
    public void close() throws IOException {
        IOException exception = null;
        for (InputStream part : parts) {
            try {
                part.close();
            } catch (IOException e) {
                if (exception == null) {
                    exception = e;
                } else {
                    exception.addSuppressed(e);
                }
            }
        }
        if (exception != null) {
            throw exception;
        }
    }
}
