package com.atlassian.bitbucket.scm.git.protocol;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Wrapper around {@link InputStream} that multiplexes all bytes that are read to a provided {@link StreamAnalyzer} for
 * analysis.
 */
public class AnalyzingInputStream extends FilterInputStream {

    private static final Logger log = LoggerFactory.getLogger(AnalyzingInputStream.class);

    private final StreamAnalyzer analyzer;

    public AnalyzingInputStream(InputStream delegate, StreamAnalyzer analyzer) {
        super(delegate);

        this.analyzer = analyzer;
    }

    @Override
    public int read() throws IOException {
        int value = super.read();
        if (value != -1) {
            analyze(new byte[]{(byte) value}, 0, 1);
        }
        return value;
    }

    @Override
    public int read(@Nonnull byte[] b, int off, int len) throws IOException {
        int bytesRead = super.read(b, off, len);
        if (bytesRead > 0) {
            analyze(b, off, bytesRead);
        }
        return bytesRead;
    }

    private void analyze(byte[] b, int off, int len) {
        if (analyzer.isDone()) {
            return;
        }

        try {
            analyzer.process(b, off, len);
        } catch (RuntimeException e) {
            log.debug("Error analyzing input", e);
        }
    }
}
