package be.fgov.ehealth.technicalconnector.tests.junit.rule;

import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Appender;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.PatternLayout;
import org.junit.rules.ExternalResource;

/**
 *
 *
 * @author EHP
 */
public class LoggingRule extends ExternalResource {

    public enum Level {
        DEBUG, INFO, WARN, ERROR
    }

    public static AppenderStep with() {
        return new LoggingRule.InnerStep();
    }

    public interface AppenderStep {

        BuildStep appender(Appender appender);

        BuildStep consoleAppender();

        BuildStep consoleAppender(Level level);

    }

    public interface BuildStep {

        AppenderStep and();

        LoggingRule build();
    }

    private Appender[] appenders;


    private LoggingRule(Appender... appenders) {
        this.appenders = appenders;
    }

    @Override
    protected void before() throws Throwable {
        for (Appender appender : appenders) {
            org.apache.log4j.Logger.getRootLogger().addAppender(appender);
        }
    }

    @Override
    protected void after() {
        for (Appender appender : appenders) {
            org.apache.log4j.Logger.getRootLogger().removeAppender(appender);
        }
    }

    private static class InnerStep implements AppenderStep, BuildStep {

        private Appender[] appenders = new Appender[]{};

        @Override
        public BuildStep appender(Appender appender) {
            appenders = (Appender[]) ArrayUtils.add(appenders, appender);
            return this;
        }

        @Override
        public BuildStep consoleAppender() {
            return consoleAppender(Level.DEBUG);
        }

        @Override
        public BuildStep consoleAppender(Level level) {
            ConsoleAppender console = new ConsoleAppender();
            String PATTERN = "%d{dd-MM-yyyy | HH:mm:ss} | %-5p | %c{1}:%L | %m%n";
            console.setLayout(new PatternLayout(PATTERN));
            console.setThreshold(org.apache.log4j.Level.toLevel(level.name()));
            console.activateOptions();
            appenders = (Appender[]) ArrayUtils.add(appenders, console);
            return this;
        }

        @Override
        public AppenderStep and() {
            return this;
        }

        @Override
        public LoggingRule build() {
            return new LoggingRule(appenders);
        }
    }
}
