/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.logging;

import java.io.File;
import java.io.IOException;

import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;


/**
 * Default implementation of JaxoLogger.
 *
 * This adds a ConsoleHandler (ie logging to standard error) whose logging
 * level is adjustable, and a FileHandler (logging to a rotating sequence
 * of log files in a given directory) which always logs everything.
 *
 * @since 2.0
 */
public final class JaxoDefaultLogger implements JaxoLogger {

    private static final Logger LOGGER = Logger.getLogger("net.sf.jaxodraw");
    private final JaxoConsoleHandler consoleHandler = new JaxoConsoleHandler();

    /**
     * Constructor. Only adds a JaxoConsoleHandler.
     */
    public JaxoDefaultLogger() {
        this(null);
    }

    /**
     * Constructor. Adds a JaxoConsoleHandler and a JaxoFileHandler.
     *
     * @param logDir The directory where log files should be stored.
     *      If this doesn't exist, it will be created.
     *      If logDir is null, no FileHandler is added.
     */
    public JaxoDefaultLogger(final String logDir) {
        // keep the logger level at finest, only set level of handlers
        LOGGER.setLevel(Level.ALL);
        LOGGER.setUseParentHandlers(false);

        LOGGER.addHandler(consoleHandler);

        if (logDir != null) {
            addFileHandler(logDir);
        }
    }


    /**
     * Sets the logging level. Forwards the Level to the ConsoleHandler,
     * the JaxoFileHandler should always log everything.
     *
     * @param level the log level to set.
     */
    public void setLevel(final Level level) {
        consoleHandler.setLevel(level);
    }

    /** {@inheritDoc} */
    public Level getLevel() {
        return consoleHandler.getLevel();
    }

    /** {@inheritDoc} */
    public boolean isLoggable(final Level level) {
        //return (getLevel().intValue() <= level.intValue());
        return consoleHandler.isLoggable(new LogRecord(level, null));
    }

    /** {@inheritDoc} */
    public void log(final Level level, final String message, final Throwable e) {
        if (e == null) {
            if (message == null) {
                throw new IllegalArgumentException("Nothing to log?");
            } else {
                LOGGER.log(level, message);
            }
        } else {
            LOGGER.log(level, (message == null ? e.getMessage() : message), e);
            if (getLevel().intValue() <= Level.FINE.intValue()) {
                e.printStackTrace();
            }
        }
    }

      //
     // private
    //

    // create log dir if it doesn't exist
    private boolean createLogDir(final File logDir) throws IOException {
        if (!logDir.exists()) {
            if (logDir.mkdirs()) {
                return true;
            } else {
                throw new IOException("Failed to create log dir: "
                        + logDir.getAbsolutePath());
            }

        }

        return false;
    }

    private void addFileHandler(final String logDir) {
        try {
            // make sure log dir exists
            final boolean dirCreated = createLogDir(new File(logDir));

            LOGGER.addHandler(new JaxoFileHandler(logDir));

            if (dirCreated) {
                LOGGER.log(Level.WARNING, "Created log directory: {0}", logDir);
            }
        } catch (IOException ex) {
            LOGGER.log(Level.WARNING, "Failed to initialize FileHandler!", ex);
            if (getLevel().intValue() <= Level.FINE.intValue()) {
                ex.printStackTrace();
            }
        }
    }

}
