package grails.plugin.lightweightdeploy.logging;

import ch.qos.logback.classic.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import static java.util.Collections.unmodifiableList;

public class LoggingConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(LoggingConfiguration.class);

    private List<AbstractLoggingConfiguration> appenderConfigurations = new ArrayList<AbstractLoggingConfiguration>();
    private Level rootLevel = Level.INFO;
    private Map<String, Level> loggers = new HashMap<String, Level>();

    public LoggingConfiguration(Map<String, ?> config) {
        if (config.containsKey("level")) {
            rootLevel = Level.toLevel(config.get("level").toString());
        }
        if (config.containsKey("appenders")) {
            List<Map<String, ?>> appendersConfig = (List<Map<String, ?>>) config.get("appenders");
            for (Map<String, ?> appenderConfig : appendersConfig) {
                appenderConfigurations.add(createAppenderConfiguration(appenderConfig));
            }
        }
        if (config.containsKey("loggers")) {
            for (Map.Entry<String, ?> entry : ((Map<String, ?>) config.get("loggers")).entrySet()) {
                loggers.put(entry.getKey(), Level.toLevel(entry.getValue().toString()));
            }
        }

        // handle deprecated logging format
        if (config.containsKey("file")) {
            logger.warn("'file' is deprecated - please move to 'appenders' list with type 'file'");
            Map<String, ?> fileConfig = (Map<String, ?>) config.get("file");
            appenderConfigurations.add(new FileLoggingConfiguration(fileConfig));
        }
        if (config.containsKey("console")) {
            logger.warn("'console' is deprecated - please move to 'appenders' list with type 'console'");
            Map<String, ?> consoleConfig = (Map<String, ?>) config.get("console");
            appenderConfigurations.add(new ConsoleLoggingConfiguration(consoleConfig));
        }
        if (config.containsKey("rootLevel")) {
            logger.warn("'rootLevel' is deprecated in favor of 'level'");
            rootLevel = Level.toLevel(config.get("rootLevel").toString());
        }
    }

    public List<AbstractLoggingConfiguration> getAppenderConfigurations() {
        return unmodifiableList(appenderConfigurations);
    }

    private static AbstractLoggingConfiguration createAppenderConfiguration(Map<String, ?> appenderConfig) {
        String type = appenderConfig.get("type").toString();
        if (type.equals("file")) {
            return new FileLoggingConfiguration(appenderConfig);
        } else if (type.equals("console")) {
            return new ConsoleLoggingConfiguration(appenderConfig);
        } else {
            throw new IllegalArgumentException("Unknown appender type '" + type + "'");
        }
    }

    @Deprecated
    public FileLoggingConfiguration getFileConfiguration() {
        for (AbstractLoggingConfiguration appenderConfig : appenderConfigurations) {
            if (appenderConfig instanceof FileLoggingConfiguration) {
                return (FileLoggingConfiguration) appenderConfig;
            }
        }
        return null;
    }

    @Deprecated
    public ConsoleLoggingConfiguration getConsoleConfiguration() {
        for (AbstractLoggingConfiguration appenderConfig : appenderConfigurations) {
            if (appenderConfig instanceof ConsoleLoggingConfiguration) {
                return (ConsoleLoggingConfiguration) appenderConfig;
            }
        }
        return null;
    }

    public Level getRootLevel() {
        return rootLevel;
    }

    public Map<String, Level> getLoggers() {
        return loggers;
    }

    @Deprecated
    public boolean hasFileConfiguration() {
        return getFileConfiguration() != null;
    }

    @Deprecated
    public boolean hasConsoleConfiguration() {
        return getConsoleConfiguration() != null;
    }

    public TimeZone getTimeZone() {
        if (!appenderConfigurations.isEmpty()) {
            return appenderConfigurations.get(0).getTimeZone();
        }
        return TimeZone.getDefault();
    }

}

@@ -3006,1084 +3006,138 @@
     
-@Deprecated%0A    public FileLoggingConfiguration getFileConfiguration() %7B%0A        for (AbstractLoggingConfiguration appenderConfig : appenderConfigurations) %7B%0A            if (appenderConfig instanceof FileLoggingConfiguration) %7B%0A                return (FileLoggingConfiguration) appenderConfig;%0A            %7D%0A        %7D%0A        return null;%0A    %7D%0A%0A    @Deprecated%0A    public ConsoleLoggingConfiguration getConsoleConfiguration() %7B%0A        for (AbstractLoggingConfiguration appenderConfig : appenderConfigurations) %7B%0A            if (appenderConfig instanceof ConsoleLoggingConfiguration) %7B%0A                return (ConsoleLoggingConfiguration) appenderConfig;%0A            %7D%0A        %7D%0A        return null;%0A    %7D%0A%0A    public Level getRootLevel() %7B%0A        return rootLevel;%0A    %7D%0A%0A    public Map%3CString, Level%3E getLoggers() %7B%0A        return loggers;%0A    %7D%0A%0A    @Deprecated%0A    public boolean hasFileConfiguration() %7B%0A        return getFileConfiguration() != null;%0A    %7D%0A%0A    @Deprecated%0A    public boolean hasConsoleConfiguration() %7B%0A        return getConsoleConfiguration() != null
+public Level getRootLevel() %7B%0A        return rootLevel;%0A    %7D%0A%0A    public Map%3CString, Level%3E getLoggers() %7B%0A        return loggers
 ;%0A  

Remove obsolete methods