package ch.polgrabia.utils;

import org.slf4j.Marker;
import org.slf4j.event.Level;
import org.slf4j.helpers.AbstractLogger;

import java.util.Properties;

public class AnsiTermLogger extends AbstractLogger {
    private final Properties properties;
    private final String loggerPropertiesPrefix;
    private Level level;

    public AnsiTermLogger(String name, Properties properties, String loggerPropertiesPrefix) {
        this.name = name;
        this.properties = properties;
        this.loggerPropertiesPrefix = loggerPropertiesPrefix;
    }

    private Level getLevel() {
        return this.level != null ? this.level : getLevelFromProperties();
    }

    private Level getLevelFromProperties() {
        String property = String.format("%s.%s.level", loggerPropertiesPrefix, name);
        String levelValue = properties.getProperty(
                property
                , "INFO");
        return Level.valueOf(levelValue);
    }

    public void setLevel(Level level) {
        this.level = level;
    }

    @Override
    protected String getFullyQualifiedCallerName() {
        return name;
    }

    @Override
    protected void handleNormalizedLoggingCall(Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable) {
        if (!isLevelEnabled(level)) {
            return;
        }

        String prefix = properties.getProperty(
                String.format("%s.%s.%s.prefix", loggerPropertiesPrefix, name, level.name().toLowerCase()), "");
        String suffix = properties.getProperty(
                String.format("%s.%s.%s.suffix", loggerPropertiesPrefix, name, level.name().toLowerCase()), "");
        // TODO I believe it's not the security-wise safest approach but well...
        System.out.printf(prefix + " " + level.name()  + (messagePattern) + suffix + "%n", arguments);

    }

    private boolean isLevelEnabled(Level level) {
        return level.toInt() >= getLevel().toInt();
    }

    @Override
    public boolean isTraceEnabled() {
        return isLevelEnabled(Level.TRACE);
    }

    @Override
    public boolean isTraceEnabled(Marker marker) {
        return isTraceEnabled();
    }

    @Override
    public boolean isDebugEnabled() {
        return isLevelEnabled(Level.DEBUG);
    }

    @Override
    public boolean isDebugEnabled(Marker marker) {
        return isDebugEnabled();
    }

    @Override
    public boolean isInfoEnabled() {
        return isLevelEnabled(Level.INFO);
    }

    @Override
    public boolean isInfoEnabled(Marker marker) {
        return isInfoEnabled();
    }

    @Override
    public boolean isWarnEnabled() {
        return isLevelEnabled(Level.WARN);
    }

    @Override
    public boolean isWarnEnabled(Marker marker) {
        return isWarnEnabled();
    }

    @Override
    public boolean isErrorEnabled() {
        return isLevelEnabled(Level.ERROR);
    }

    @Override
    public boolean isErrorEnabled(Marker marker) {
        return isErrorEnabled();
    }
}
