package me.teridax.jcash;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.logging.*;

/**
 * Utility class for providing a global logger for the entire application instance at runtime
 */
public final class Logging {

    /**
     * Publicly available logger instance.
     */
    public static final Logger LOGGER = Logger.getLogger(Logging.class.getName());

    /**
     * Folder the log files are stored in, relative to the file containing the class
     */
    private static final String LOG_FOLDER_NAME = "logs/";
    /**
     * Format for the date time used for log files
     */
    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd_HH-mm-ss";

    /**
     * Initialize the global system logger.
     * Adds a file logging handler
     */
    static void initializeSystemLogger(Level level) {
        LogManager.getLogManager().reset();

        createConsoleLogger(level);
        createFileLogger(level);

        LOGGER.setLevel(level);
    }

    /**
     * Add a console log handler writing to the applications stderr
     *
     * @param level the level to set the handler to
     */
    private static void createConsoleLogger(Level level) {
        var ch = new ConsoleHandler();
        ch.setLevel(level);
        LOGGER.addHandler(ch);
    }

    /**
     * Create a log handler writing to a file.
     * The file will be located in a folder directly besides the application
     * with the name LOG_FOLDER_NAME. The name will follow the format DATE_TIME_FORMAT plus "log" as
     * file extension.
     *
     * @param level the log level to set the handler to
     */
    private static void createFileLogger(Level level) {
        // setup log file name
        var now = LocalDateTime.now();
        var dateTime = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT).format(now);
        var logFileName = LOG_FOLDER_NAME + dateTime + ".log";

        // setup the folder for the logs
        initializeLogFolder();

        try {
            var fh = new FileHandler(logFileName);
            fh.setLevel(level);
            LOGGER.addHandler(fh);
        } catch (Exception e) {
            LOGGER.warning("Unable to initialize logging for file: " + logFileName);
        }
    }

    /**
     * Checks if the folder containing log files is present.
     * If the folder does not exist, the function will create a new folder.
     */
    private static void initializeLogFolder() {
        var folderPath = Path.of(LOG_FOLDER_NAME);

        if (Files.isDirectory(folderPath))
            return;

        try {
            Files.createDirectory(folderPath);
        } catch (IOException e) {
            LOGGER.warning("Unable to create directory: " + folderPath);
        }
    }
}
