/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.jul;

//note: NO import of Logger, Level, LogManager to prevent conflicts JUL/log4j
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map.Entry;

import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationListener;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.Reconfigurable;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;


/**
 * Test the Log4jBridgeHandler.
 * Requires some configurations in the log-config-files, for format/layout
 * see also jul() and log4j():
 * - JUL-config ("logging-test.properties", must be set on JVM-start via "-D..."):
 *   + handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler, java.util.logging.ConsoleHandler
 *   + org.apache.logging.log4j.jul.Log4jBridgeHandler.appendSuffix = _JUL
 *   + java.util.logging.ConsoleHandler.level = ALL
 *   + java.util.logging.SimpleFormatter.format = JUL:  %1$tT.%1$tL %4$s [%3$s: %2$s]  -  %5$s%6$s%n
 *   + .level = FINER
 * - log4j2-config ("log4j2-test.xml"):
 *   + <Root level="TRACE">
 *   + <Appenders> <Console> with target="SYSTEM_ERR", follow="true",
 *      <PatternLayout> "log4j2:  %d{HH:mm:ss.SSS} %5level - [%thread][%logger: %class/%method/%line]  -  %message%n"
 *
 * This test needs to capture syserr because it uses java.util.logging.ConsoleHandler.
 * Also, it performs some outputs to console (sysout and syserr); see also field OUTPUT_CAPTURED.
 *
 * The code also contains evaluation/test code for development time. It is not used for the unit tests
 * but kept here for reference and info. See field DEVTEST.
 */
@FixMethodOrder(org.junit.runners.MethodSorters.NAME_ASCENDING)    // is nicer for manually checking console output
public class Log4jBridgeHandlerTest {
    /** Perform developer tests? */
    private static final boolean DEVTEST = false;

    /** Do output the captured logger-output to stdout? */
    private static final boolean OUTPUT_CAPTURED = !DEVTEST  &&  Boolean.parseBoolean(
            System.getProperty("log4j.Log4jBridgeHandlerTest.outputCaptured"));

    /** This classes' simple name = relevant part of logger name. */
    private static final String CSNAME = Log4jBridgeHandlerTest.class.getSimpleName();
    // loggers used in many tests
    private static final java.util.logging.Logger julLog = java.util.logging.Logger.getLogger(Log4jBridgeHandlerTest.class.getName());
    private static final org.apache.logging.log4j.Logger log4jLog = org.apache.logging.log4j.LogManager.getLogger();

    // capture sysout/syserr
    //@Rule  public final SystemErrRule systemOutRule = new SystemErrRule().enableLog();
    private static final ByteArrayOutputStream sysoutBytes = new ByteArrayOutputStream(1024);
    private static PrintStream prevSysErrStream;


    @BeforeClass
    public static void beforeClass() {
        // debug output to easily recognize misconfig.:
        //System.out.println("sys-props:\n" + System.getProperties());
        System.out.println("sysout:  logging-cfg-file:  " + System.getProperty("java.util.logging.config.file"));
        if (DEVTEST)  devTestBeforeClass();    // call before stderr capturing

        // JUL does not like setting stderr inbetween, so set it once and reset collecting stream
        // for each method; (thus com.github.stefanbirkner:system-rules:SystemErrRule cannot be used)
        System.err.println("vvv--- BEGIN capturing output to stderr ---vvv"
                + "   (do output of captured text to orig. stderr: " + OUTPUT_CAPTURED + ")");
        prevSysErrStream = System.err;
        System.setErr(new PrintStream(sysoutBytes, true));
    }

    @AfterClass
    public static void afterClass() {
        // reset sysout/err to original value
        System.setErr(prevSysErrStream);
        System.err.println("^^^--- END capturing output of stderr ---^^^");
    }


    @Before
    public void beforeTest() {
        // reset sysout collector
        sysoutBytes.reset();
    }



    /** Assert that captured sysout matches given regexp (any text may follow afterwards). */
    private void assertSysoutMatches(String regex) {
        //String logOutput = systemOutRule.getLogWithNormalizedLineSeparator();
        String logOutput = sysoutBytes.toString();
        if (OUTPUT_CAPTURED)  prevSysErrStream.print(logOutput);
        logOutput = logOutput.replace("\r\n", "\n");
        regex = regex + "(.|\\n)*";        // allow any text with NL afterwards
        assertTrue("Unmatching output:\n" + logOutput + "\n-- vs: --\n" + regex + "\n----", logOutput.matches(regex));
    }

    /** Get regex for a JUL console output. Must match JUL-Console-Formatter! */
    private String jul(java.util.logging.Level lvl, String locationPartRE,
            String msgPartRE, String exceptionClassAndMsgRE) {
        return "JUL:.*" + lvl.getLocalizedName() + ".*" + CSNAME
                + ".*" + locationPartRE + ".*" + msgPartRE + ".*\n"    // use real \n at end here for better error output
                + (exceptionClassAndMsgRE == null  ?  ""
                        :  ".*" + exceptionClassAndMsgRE + ".*\\n(\tat .*\\n)*\\n?");
    }

    /** Get regex for a log4j console output. Must match log4j2-Console-Layout! */
    private String log4j(org.apache.logging.log4j.Level lvl, boolean julBridged,
            String methodPartRE, String msgPartRE, String exceptionClassAndMsgRE) {
        return "log4j2:.*" + lvl.name() + ".*" + CSNAME + (julBridged ? "\\._JUL" : "")
                + ".*" + CSNAME + "/\\w*" + methodPartRE + "\\w*/.*"
                + msgPartRE + ".*\n"        // use real \n at end here for better error output
                + (exceptionClassAndMsgRE == null  ?  ""
                    :  ".*" + exceptionClassAndMsgRE + ".*\\n(\tat .*\\n)*\\n?");
    }



    @Test
    public void test1SimpleLoggings1Jul() {
        julLog.info("Test-'Info'-Log with JUL");
        julLog.fine("Test-'Fine'-Log with JUL");
        julLog.finest("Test-'Finest'-Log with JUL");    // should not be logged because JUL-level is FINER
        julLog.warning("Test-'Warn'-Log with JUL");    // thus add another log afterwards to allow checking
        String methodRE = "SimpleLoggings1Jul";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.INFO, true, methodRE, "'Info'-Log with JUL", null)
                + jul(java.util.logging.Level.INFO, methodRE, "'Info'-Log with JUL", null)
                + log4j(org.apache.logging.log4j.Level.DEBUG, true, methodRE, "'Fine'-Log with JUL", null)
                + jul(java.util.logging.Level.FINE, methodRE, "'Fine'-Log with JUL", null)
                // no finest/trace
                + log4j(org.apache.logging.log4j.Level.WARN, true, methodRE, "'Warn'-Log with JUL", null)
                + jul(java.util.logging.Level.WARNING, methodRE, "'Warn'-Log with JUL", null)
                );
    }

    @Test
    public void test1SimpleLoggings2Log4jDirect() {
        log4jLog.info("Test-'Info'-Log with log4j2");
        log4jLog.debug("Test-'Debug'-Log with log4j2");
        log4jLog.trace("Test-'Trace'-Log with log4j2");
        String methodRE = "SimpleLoggings2Log4jDirect";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.INFO, false, methodRE, "'Info'-Log with log4j2", null)
                + log4j(org.apache.logging.log4j.Level.DEBUG, false, methodRE, "'Debug'-Log with log4j2", null)
                + log4j(org.apache.logging.log4j.Level.TRACE, false, methodRE, "'Trace'-Log with log4j2", null)
                );
    }


    @Test
    public void test2SubMethod() {
        subMethodWithLogs();        // location info is sub method now
        String methodRE = "subMethodWithLogs";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.DEBUG, true, methodRE, "'Fine'-Log with JUL in subMethod", null)
                + jul(java.util.logging.Level.FINE, methodRE, "'Fine'-Log with JUL in subMethod", null)
                + log4j(org.apache.logging.log4j.Level.INFO, false, methodRE, "'Info'-Log with log4j2 in subMethod", null)
                );
    }
    private void subMethodWithLogs() {
        julLog.fine("Test-'Fine'-Log with JUL in subMethod");
        log4jLog.info("Test-'Info'-Log with log4j2 in subMethod");
    }


    @Test
    public void test3JulFlow1() {
        // note: manually given source information get lost in log4j!
        julLog.entering("enteringExampleClassParam", "enteringExampleMethodParam");
        String methodRE = "JulFlow";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE, "ENTRY", null)
                + jul(java.util.logging.Level.FINER, "enteringExampleClassParam enteringExampleMethodParam", "ENTRY", null)
                );
    }

    @Test
    public void test3JulFlow2() {
        // note: manually given source information get lost in log4j!
        julLog.entering("enteringExampleClassParam", "enteringExampleMethodParam_withParams",
                new Object[] {"with some", "parameters", 42} );
        String methodRE = "JulFlow";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
                        "ENTRY.*with some.*param.*42", null)
                + jul(java.util.logging.Level.FINER, "enteringExampleClassParam enteringExampleMethodParam_withParams",
                        "ENTRY.*with some.*param.*42", null)
                );
    }

    @Test
    public void test3JulFlow3() {
        // note: manually given source information get lost in log4j!
        julLog.exiting("exitingExampleClassParam", "exitingExampleMethodParam",
                Arrays.asList("array of Strings", "that are the exit", "result"));
        String methodRE = "JulFlow";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
                        "RETURN.*array of Str.*that are.*result", null)
                + jul(java.util.logging.Level.FINER, "exitingExampleClassParam exitingExampleMethodParam",
                        "RETURN.*array of Str.*that are.*result", null)
                );
    }

    @Test
    public void test3JulFlow4() {
        // note: manually given source information get lost in log4j!
        julLog.throwing("throwingExampleClassParam", "throwingExampleMethodParam",
                new IllegalStateException("ONLY TEST for JUL-throwing()"));
        String methodRE = "JulFlow";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.TRACE, true, methodRE,
                        "THROW",  "IllegalStateException.*ONLY TEST for JUL-throwing")
                + jul(java.util.logging.Level.FINER, "throwingExampleClassParam throwingExampleMethodParam",
                        "THROW",  "IllegalStateException.*ONLY TEST for JUL-throwing")
                );
    }



    @Test
    public void test4JulSpecials1() {
        julLog.log(java.util.logging.Level.WARNING, "JUL-Test via log() as warning with exception",
                new java.util.zip.DataFormatException("ONLY TEST for JUL.log()"));
        String methodRE = "JulSpecials";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.WARN, true, methodRE,
                        "JUL-Test via log\\(\\) as warning",  "DataFormatException.*ONLY TEST for JUL")
                + jul(java.util.logging.Level.WARNING, methodRE, "JUL-Test via log\\(\\) as warning",
                        "DataFormatException.*ONLY TEST for JUL")
                );
    }

    @Test
    public void test4JulSpecials2() {
        // test with MessageFormat
        julLog.log(java.util.logging.Level.INFO, "JUL-Test via log() with parameters (0={0}, 1={1}, 2={2,number,##000.0})",
                new Object[] {"a", "b", 42} );
        String methodRE = "JulSpecials";
        assertSysoutMatches(
                log4j(org.apache.logging.log4j.Level.INFO, true, methodRE,
                        "JUL-Test via log\\(\\) with parameters \\(0=a, 1=b, 2=042.0\\)", null)
                + jul(java.util.logging.Level.INFO, methodRE,
                        "JUL-Test via log\\(\\) with parameters \\(0=a, 1=b, 2=042.0\\)", null)
                );
    }

    // no test for logrb(ResourceBundle)-case as this is very specific and seldom used (in
    // my opinion); and it does not add any real thing to test here


    private void assertLogLevel(String loggerName, java.util.logging.Level julLevel) {
        java.util.logging.Logger lg = java.util.logging.LogManager.getLogManager().getLogger(loggerName);
        assertEquals("Logger '" + loggerName + "'", julLevel, (lg == null  ?  null  :  lg.getLevel()));
    }

    @Test
    public void test5LevelPropFromConfigFile() {
        // JUL levels are set from config files and the initial propagation
        assertLogLevel("", java.util.logging.Level.FINE);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1", java.util.logging.Level.FINE);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested1", java.util.logging.Level.FINER);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested2.deeplyNested", java.util.logging.Level.WARNING);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2", java.util.logging.Level.ALL);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested.deeplyNested", java.util.logging.Level.INFO);
        // these are set in logging.properties but not in log4j2.xml:
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate2.nested", null);
        assertLogLevel("javax.mail", null);
        // these should not exist:
        assertLogLevel("log4j.Log4jBridgeHandlerTest", null);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested", null);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested1.deeplyNested", null);
    }


    @Test
    public void test5LevelPropSetLevel() {
        String name = "log4j.test.new_logger_level_set";
        Configurator.setLevel(name, org.apache.logging.log4j.Level.DEBUG);
        assertLogLevel(name, java.util.logging.Level.FINE);
        test5LevelPropFromConfigFile();    // the rest should be untouched!

        name = "log4j.Log4jBridgeHandlerTest.propagate1.nested1";
        Configurator.setLevel(name, org.apache.logging.log4j.Level.WARN);
        assertLogLevel(name, java.util.logging.Level.WARNING);
        // the others around should be untouched
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1", java.util.logging.Level.FINE);
        assertLogLevel("log4j.Log4jBridgeHandlerTest.propagate1.nested2.deeplyNested", java.util.logging.Level.WARNING);

        // note: no need to check for the other set[Root]Level() methods, because they all call
        // loggerContext.updateLoggers() which calls firePropertyChangeEvent()
    }


    @Test
    public void test5LevelPropGC() {
        // this test will fail if you comment out "julLoggerRefs.add(julLog);" in propagateLogLevels()
        test5LevelPropFromConfigFile();    // at start, all should be fine
        java.util.logging.Logger julLogRef = java.util.logging.Logger
                .getLogger("log4j.Log4jBridgeHandlerTest.propagate1.nested1");
        System.gc();    // a single call is sufficient
        System.out.println("sysout:  test5LevelPropGC() still has reference to JUL-logger: "
                + julLogRef.getName() + " / " + julLogRef);
        try {
            test5LevelPropFromConfigFile();    // even after GC the not referenced loggers should still be there
        } catch (Throwable t) {
            debugPrintJulLoggers("After GC");
            // => JUL root logger, above explicitly referenced logger and its parent ("...propagate1")
            //    and the global referenced julLog ("...jul.Log4jBridgeHandlerTest") are still there, the
            //    others are null-references now
            throw t;
        }
    }


    /** Print all available JUL loggers to stdout. */
    private static void debugPrintJulLoggers(String infoStr) {
        java.util.logging.LogManager julMgr = java.util.logging.LogManager.getLogManager();
        System.out.println("sysout:  " + infoStr + " - for " + julMgr);
        java.util.List<String> txt = new java.util.ArrayList<>();
        int n = 1;
        for (Enumeration<String> en = julMgr.getLoggerNames();  en.hasMoreElements(); ) {
            String ln = en.nextElement();
            java.util.logging.Logger lg = julMgr.getLogger(ln);
            if (lg == null) {
                txt.add("(!null-Logger '" + ln + "')  #" + n);
            } else if (lg.getLevel() == null) {
                txt.add("(null-Level Logger '" + ln + "')  #" + n);
            } else {
                txt.add("Logger '" + ln + "',  lvl = " + lg.getLevel() + "  #" + n);
            }
            n++;
        } // for
        java.util.Collections.sort(txt, String.CASE_INSENSITIVE_ORDER);
        for (String s : txt) {
            System.out.println("  - " + s);
        }
    }




////////////////
////////////////   INTERNAL DEVELOPER TESTS follow
////////////////   (these are NOT neccessary for unit test but source is kept here for reference and info)


    static {
        if (DEVTEST) {
            System.out.println("sysout:  static init. BEGIN");

            // get log4j context impl. (requires log4j-core!)
            // note:  "LogManager.getContext();"  does not work, it returns another instance!?!
            LoggerContext context = LoggerContext.getContext(false);    // this matches Configurator.setLevel() impl.
            Configuration cfg = context.getConfiguration();
            // print real loggers (=> is empty when using LogManager.getContext()!?! only contains already instantiated loggers)
            System.out.println("LogCtx " + context + " '" + context.getName() + "',  loc = "
                    + context.getConfigLocation() + ",  cfg = " + cfg + " = " + System.identityHashCode(cfg));
            for (org.apache.logging.log4j.Logger lg : context.getLoggers()) {
                System.out.println("- Logger '" + lg.getName() + "',  lvl = " + lg.getLevel());
            }
            // print logger configurations (=> all loggers with level are present here)
            System.out.println("Loggers in Cfg:");
            for (Entry<String, LoggerConfig> entry : cfg.getLoggers().entrySet()) {
                LoggerConfig lcfg = entry.getValue();
                System.out.println("- '" + entry.getKey() + "' = '" + lcfg.getName() + "' / "
                        + lcfg.getLevel() + "; " + lcfg);
            }

            // print JUL loggers (=> is completely init. here, even if first JUL log and BridgeHandler-creation happens later)
            debugPrintJulLoggers("in static-class-init");
            /* java.util.logging.LogManager julMgr = java.util.logging.LogManager.getLogManager();
            System.out.println("\nJUL-Loggers for " + julMgr);
            for (Enumeration<String> en = julMgr.getLoggerNames();  en.hasMoreElements(); ) {
                String ln = en.nextElement();
                java.util.logging.Logger lg = julMgr.getLogger(ln);
                if (lg.getLevel() == null) {
                    System.out.println("-    (null-Level Logger '" + ln + "')");
                } else {
                    System.out.println("- Logger '" + ln + "',  lvl = " + lg.getLevel());
                }
            } */

            // changing of log4j config. is to be done via log4j.core.config.Configurator,
            // e.g. setLevel(loggerName, newLevel)
            // Note: the (internal) log4j.core.Logger has a setLevel() but this should not be used.
            CfgListener listener = new CfgListener();
            cfg.addListener(listener);    // => onChange() is never called: not on start, not on setLevel
            context.addPropertyChangeListener(listener);

            System.out.println("sysout:  static init. END");
        } // if
    }


    private static void devTestBeforeClass() {
        log4jLog.info("Dummy-Start-Log in beforeClass()");    // force init. of log4j (needed?? does not harm)
        @SuppressWarnings("resource")
        LoggerContext context = LoggerContext.getContext(false);    // this matches Configurator.setLevel() impl. (instead of "LogManager.getContext();")
        System.out.println("beforeClass():  LogCtx " + context + " '" + context.getName() + "',  loc = " + context.getConfigLocation()
                + ",  cfg = " + context.getConfiguration());
        for (org.apache.logging.log4j.Logger lg : context.getLoggers()) {
            System.out.println("- Logger '" + lg.getName() + "',  lvl = " + lg.getLevel());
        }

        // force level change
        System.out.println("sysout:  now calling log4j-setLevel()");
        Configurator.setLevel("log4jTest.Dummy_set_in_devTestBeforeClass", org.apache.logging.log4j.Level.DEBUG);
    }


    private static class CfgListener implements ConfigurationListener, PropertyChangeListener {
        public CfgListener() {
            System.out.println("sysout:  CfgListener created: " + this);
        }

        @Override
        public void onChange(Reconfigurable reconfigurable) {    // from ConfigurationListener
            System.out.println("sysout:  CfgListener.CfgLi-onChange(): " + reconfigurable
                    + " = " + System.identityHashCode(reconfigurable));
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {    // from PropertyChangeListener
            System.out.println("sysout:  CfgListener.PropChLi-propertyChange(): " + evt);
        }
    }

}
