/**
 *  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.util;

import java.util.logging.Level;

import net.sf.jaxodraw.logging.JaxoDefaultLogger;
import net.sf.jaxodraw.logging.JaxoLogger;

import junit.framework.TestCase;

/**
 * Tests JaxoLog.
 */
public class JaxoLogTest extends TestCase {
    private final TestLogger testLogger = new TestLogger();

    /** Constructor: just calls super.
     * @param testName The name of this test.
     */
    public JaxoLogTest(String testName) {
        super(testName);
    }

    /** JUnit setup: initialize the object. */
    @Override
    protected void setUp() {
        testLogger.init();
    }
    /**
     * Test of setLogger method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testSetLogger() {
        JaxoLog.setLogger(null);
        assertNotNull("Null logger returned!", JaxoLog.getLogger());

        // test null logger
        JaxoLog.setLevel(JaxoLog.INFO);
        assertEquals(Level.OFF.intValue(), JaxoLog.getCurrentLevel());
        assertFalse(JaxoLog.isLoggable(JaxoLog.DEBUG));
        JaxoLog.debug("this should go to Nirvana");
    }

    /**
     * Test of setLevel method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testSetLevel() {
        JaxoLog.setLogger(new JaxoDefaultLogger());
        JaxoLog.setLevel(JaxoLog.DEBUG);
        assertEquals(JaxoLog.DEBUG, JaxoLog.getCurrentLevel());
        JaxoLog.setLevel(Level.FINEST.intValue());
        assertEquals(JaxoLog.DEBUG, JaxoLog.getCurrentLevel());
    }

    /**
     * Test of isLoggable method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testIsLoggable() {
        JaxoLog.setLogger(new JaxoDefaultLogger());
        JaxoLog.setLevel(JaxoLog.DEBUG);
        assertTrue(JaxoLog.isLoggable(JaxoLog.DEBUG));
        assertTrue(JaxoLog.isLoggable(JaxoLog.INFO));
        assertTrue(JaxoLog.isLoggable(JaxoLog.WARN));

        JaxoLog.setLevel(JaxoLog.INFO);
        assertFalse(JaxoLog.isLoggable(JaxoLog.DEBUG));
        assertTrue(JaxoLog.isLoggable(JaxoLog.INFO));
        assertTrue(JaxoLog.isLoggable(JaxoLog.WARN));

        JaxoLog.setLevel(JaxoLog.WARN);
        assertFalse(JaxoLog.isLoggable(JaxoLog.DEBUG));
        assertFalse(JaxoLog.isLoggable(JaxoLog.INFO));
        assertTrue(JaxoLog.isLoggable(JaxoLog.WARN));
    }

    /**
     * Test of debug method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testDebug() {
        JaxoLog.setLogger(testLogger);
        JaxoLog.debug("message");
        assertEquals("message", testLogger.getMsg());
        JaxoLog.debugI18N("");
        assertEquals("", testLogger.getMsg());
        JaxoLog.debug(new Exception());
        assertNotNull(testLogger.getCause());

        JaxoLog.debug("message2", null);
        assertEquals("message2", testLogger.getMsg());
        assertNull(testLogger.getCause());
        JaxoLog.debugI18N("", null);
        assertEquals("", testLogger.getMsg());
        assertNull(testLogger.getCause());
    }

    /**
     * Test of info method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testInfo() {
        JaxoLog.setLogger(testLogger);
        JaxoLog.info("message");
        assertEquals("message", testLogger.getMsg());
        JaxoLog.infoI18N("");
        assertEquals("", testLogger.getMsg());
        JaxoLog.info(new Exception());
        assertNotNull(testLogger.getCause());

        JaxoLog.info("message2", null);
        assertEquals("message2", testLogger.getMsg());
        assertNull(testLogger.getCause());
        JaxoLog.infoI18N("", null);
        assertEquals("", testLogger.getMsg());
        assertNull(testLogger.getCause());
    }

    /**
     * Test of warn method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testWarn() {
        JaxoLog.setLogger(testLogger);
        JaxoLog.warn("message");
        assertEquals("message", testLogger.getMsg());
        JaxoLog.warnI18N("");
        assertEquals("", testLogger.getMsg());
        JaxoLog.warn(new Exception());
        assertNotNull(testLogger.getCause());

        JaxoLog.warn("message2", null);
        assertEquals("message2", testLogger.getMsg());
        assertNull(testLogger.getCause());
        JaxoLog.warnI18N("", null);
        assertEquals("", testLogger.getMsg());
        assertNull(testLogger.getCause());
    }

    /**
     * Test of log method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testLog() {
        JaxoLog.setLogger(testLogger);
        JaxoLog.log(JaxoLog.DEBUG, "");
        assertEquals(testLogger.getLogLevel().intValue(), JaxoLog.DEBUG);
        JaxoLog.log(JaxoLog.INFO, "", new Exception());
        assertEquals(testLogger.getLogLevel().intValue(), JaxoLog.INFO);
        JaxoLog.log(JaxoLog.WARN, new Exception());
        assertEquals(testLogger.getLogLevel().intValue(), JaxoLog.WARN);

        JaxoLog.logI18N(JaxoLog.DEBUG, "");
        assertEquals(testLogger.getLogLevel().intValue(), JaxoLog.DEBUG);
        JaxoLog.logI18N(JaxoLog.INFO, "", new Exception());
        assertEquals(testLogger.getLogLevel().intValue(), JaxoLog.INFO);
    }

    /**
     * Test of getLevelFor method, of class net.sf.jaxodraw.util.JaxoLog.
     */
    public void testGetLevelFor() {
        assertEquals(JaxoLog.getLevelFor(JaxoLog.DEBUG), Level.FINE);
        assertEquals(JaxoLog.getLevelFor(JaxoLog.INFO), Level.INFO);
        assertEquals(JaxoLog.getLevelFor(JaxoLog.WARN), Level.WARNING);

        assertEquals(JaxoLog.getLevelFor(Level.FINEST.intValue()), Level.FINE);
        assertEquals(JaxoLog.getLevelFor(Level.CONFIG.intValue()), Level.FINE);
        assertEquals(JaxoLog.getLevelFor(Level.SEVERE.intValue()), Level.WARNING);
    }

    private class TestLogger implements JaxoLogger {
        private Level logLevel;
        private Level currentLevel = Level.INFO;
        private Throwable cause;
        private String msg;

        public void init() {
            logLevel = null;
            msg = null;
            cause = null;
            currentLevel = Level.INFO;
        }

        /** {@inheritDoc} */
        public void setLevel(Level level) {
            currentLevel = level;
        }

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

        /** {@inheritDoc} */
        public boolean isLoggable(Level level) {
            return (level.intValue() >= currentLevel.intValue());
        }

        /** {@inheritDoc} */
        public void log(Level level, String message, Throwable e) {
            logLevel = level;
            msg = message;
            cause = e;
        }

        public Level getLogLevel() {
            return logLevel;
        }

        public Throwable getCause() {
            return cause;
        }

        public String getMsg() {
            return msg;
        }

    }
}
