package zmo.technology.lite.logging;

import java.io.PrintWriter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

public interface ZeroLogger {

    static Map<String, Logger> INIT_LOGGERS = new ConcurrentHashMap<>();

    static Logger getLogger(String name, Level level) {
        String loggerName = name + "." + level.getName();
        if (!INIT_LOGGERS.containsKey(loggerName)) {
            INIT_LOGGERS.put(loggerName, Logger.getLogger(loggerName));
            INIT_LOGGERS.get(loggerName).setLevel(level);
            Handler[] hs = INIT_LOGGERS.get(loggerName).getHandlers();
            for (Handler h : hs) {
                h.close();
                INIT_LOGGERS.get(loggerName).removeHandler(h);
            }
            try {
                ZeroLoggerStreamHandler streamHandler = new ZeroLoggerStreamHandler(name, level);
                INIT_LOGGERS.get(loggerName).setUseParentHandlers(false);
                INIT_LOGGERS.get(loggerName).addHandler(streamHandler);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return INIT_LOGGERS.get(loggerName);
    }

    public static Logger severeLogger() {
        return getLogger("zero", Level.SEVERE);
    }

    default void severe(String severe) {
        severeLogger().severe(severe);
    }

    default void severe(Exception e) {
        ZeroLogWriter writer = new ZeroLogWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        e.printStackTrace(printWriter);
        severelns(writer.toArray());
        printWriter.close();
    }

    default void severelns(String... fatals) {
        severe(String.join("\n", fatals) + "\n");
    }

    public static void SEVERE(String severe) {
        severeLogger().severe(severe);
    }

    public static void SEVERE(Exception e) {
        ZeroLogWriter writer = new ZeroLogWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        e.printStackTrace(printWriter);
        SEVERELNS(writer.toArray());
        printWriter.close();
    }

    public static void SEVERELNS(String... severes) {
        SEVERE(String.join("\n", severes) + "\n");
    }

    public static Logger warningLogger() {
        return getLogger("zero", Level.WARNING);
    }

    default void warn(String warn) {
        warningLogger().warning(warn);
    }

    default void warnlns(String... warns) {
        warn(String.join("\n", warns) + "\n");
    }

    public static void WARN(String warn) {
        warningLogger().warning(warn);
    }

    public static void WARNLNS(String... warns) {
        WARN(String.join("\n", warns) + "\n");
    }

    public static Logger infoLogger() {
        return getLogger("zero", Level.INFO);
    }

    default void info(String info) {
        infoLogger().info(info);
    }

    default void infolns(String... infos) {
        info(String.join("\n", infos) + "\n");
    }

    public static void INFO(String info) {
        infoLogger().info(info);
    }

    public static void INFOLNS(String... infos) {
        INFO(String.join("\n", infos) + "\n");
    }
}
