package be.iminds.ilabt.jfed.util;

import org.slf4j.Logger;
import org.slf4j.event.Level;

import java.io.IOException;
import java.io.OutputStream;

/**
 * User: twalcari
 * Date: 5/30/2016
 * Time: 10:04
 */
public final class LoggerOutputStream extends OutputStream {

    @FunctionalInterface
    private interface LoggingFunction {
        void log(String arg);
    }

    private final Logger log;
    private final org.slf4j.event.Level level;
    private final LoggingFunction loggingFunction;
    private final String pretext;

    /**
     * The internal memory for the written bytes.
     */
    private String mem = "";

    public LoggerOutputStream(Logger log, Level level, String pretext) {
        this.log = log;
        this.level = level;

        switch (this.level){
            case TRACE: loggingFunction = log::trace; break;
            case DEBUG: loggingFunction = log::debug; break;
            case INFO: loggingFunction = log::info; break;
            case WARN: loggingFunction = log::warn; break;
            case ERROR: loggingFunction = log::error; break;
            default: throw new IllegalArgumentException("Unexpected error level");
        }

        this.pretext = pretext;
    }

    @Override
    public void write(int b) throws IOException {
        byte[] bytes = new byte[1];
        bytes[0] = (byte) (b & 0xff);
        mem = mem + new String(bytes);

        if (mem.endsWith("\n")) {
            mem = mem.substring(0, mem.length() - 1);
            writeLine();
        }
    }

    /**
     * Flushes the output stream.
     */
    public void writeLine() {
        loggingFunction.log(pretext + mem);
        mem = "";
    }

    @Override
    public void close() throws IOException {
        if (!mem.isEmpty())
            writeLine();
    }
}
