/*
 * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import sun.util.logging.PlatformLogger;

/**
 * @test
 * @bug     8159245
 * @summary Tests configuration of loggers.
 * @modules java.logging/sun.util.logging.internal java.base/sun.util.logging
 * @run  main/othervm SystemLoggerConfigTest
 *
 * @author danielfuchs
 */
public class SystemLoggerConfigTest {

    static Logger createSystemLogger(String name) {
        return sun.util.logging.internal.LoggingProviderImpl.getLogManagerAccess()
                .demandLoggerFor(LogManager.getLogManager(), name,
                                 Thread.class.getModule());
    }

    static PlatformLogger createPlatformLogger(String name) {
        return PlatformLogger.getLogger(name);
    }

    private static void assertFalse(boolean value, String msg) {
        assertEquals(false, value, msg);
    }
    private static void assertEquals(boolean expected, boolean actual, String msg) {
        if (expected != actual) {
            throw new AssertionError(msg+": expected: " + expected + " actual: " + actual);
        }
    }
    private static void assertEquals(int expected, int actual, String msg) {
        if (expected != actual) {
            throw new AssertionError(msg+": expected: " + expected + " actual: " + actual);
        }
    }
    private static void assertEquals(long expected, long actual, String msg) {
        if (expected != actual) {
            throw new AssertionError(msg+": expected: " + expected + " actual: " + actual);
        }
    }
    private static void assertEquals(Object expected, Object actual, String msg) {
        if (!Objects.equals(expected, actual)) {
            throw new AssertionError(msg+": expected: " + expected + " actual: " + actual);
        }
    }

    static class TestHandler extends Handler {
        private final List<LogRecord> records = new CopyOnWriteArrayList<>();
        public TestHandler() {
            super();
            setLevel(Level.ALL);
        }

        @Override
        public void publish(LogRecord lr) {
            records.add(lr);
        }

        public List<LogRecord> drain() {
            List<LogRecord> list = new ArrayList<>(records);
            records.clear();
            return list;
        }

        public void close() {
            records.clear();
        }

        public void flush() {
        }

    }

    public static class TestHandler1 extends TestHandler {
        final static AtomicLong COUNT = new AtomicLong();
        public TestHandler1() {
            COUNT.incrementAndGet();
        }
    }

    public static class TestHandler2 extends TestHandler {
        final static AtomicLong COUNT = new AtomicLong();
        public TestHandler2() {
            COUNT.incrementAndGet();
        }
    }

    static enum TestCase { WITHSECURITY, NOSECURITY }

    public static void main(String[] args) {
        launch();
    }

    public static void launch() {
        try {
            test("1", ".child");
            test("2", "");
            testUpdateConfiguration("3");
            testSetPlatformLevel("4");
        } catch (IOException io) {
            throw new UncheckedIOException(io);
        }
    }

    public static void test(String step, String ext)
            throws IOException {

        System.out.println("\n*** Testing " + step + ext);

        final String systemName1a = "system.logger.one.a." + step + ext;
        final String systemName1b = "system.logger.one.b." + step + ext;
        final String appName1a = "system.logger.one.a." + step;
        final String appName1b = "system.logger.one.b." + step;
        final String msg1a = "logger name: " + systemName1a;
        final String msg1b = "logger name: " + systemName1b;
        final String systemName2 = "system.logger.two." + step + ext;
        final String appName2 = "system.logger.two." + step;
        final String msg2 = "logger name: " + systemName2;
        final String systemName3 = "system.logger.three." + step + ext;
        final String appName3 = "system.logger.three." + step;
        final String msg3 = "logger name: " + systemName3;
        List<LogRecord> records;

        System.out.println("\n[Case #1] Creating platform logger: " + systemName1a);
        PlatformLogger system1a = createPlatformLogger(systemName1a);
        System.out.println("    Creating platform logger: " + systemName1b);
        PlatformLogger system1b = createPlatformLogger(systemName1b);
        System.out.println("    Adding handler on root logger...");
        TestHandler test1 = new TestHandler();
        Logger.getLogger("").addHandler(test1);

        System.out.println("    Creating and configuring app logger: " + appName1a
                + ", " + appName1b);
        Logger app1a = Logger.getLogger(appName1a);
        app1a.setLevel(Level.INFO);
        Logger app1b = Logger.getLogger(appName1b);
        app1b.setLevel(Level.INFO);
        assertFalse(system1a.isLoggable(PlatformLogger.Level.FINEST),
                "Unexpected level for " + system1a);
        System.out.println("    Configuring root logger...");
        Logger.getLogger("").setLevel(Level.FINEST);
        System.out.println("    Logging through system logger: " + systemName1a);
        system1a.finest(msg1a);
        Reference.reachabilityFence(app1a);
        records = test1.drain();
        assertEquals(0, records.size(), "Unexpected size for " + records.toString());
        System.out.println("    Logging through system logger: " + systemName1b);
        system1b.finest(msg1b);
        Reference.reachabilityFence(app1b);
        records = test1.drain();
        assertEquals(0, records.size(), "Unexpected size for " + records.toString());
        Logger.getLogger("system.logger.one.a").finest("system.logger.one.a");
        records = test1.drain();
        assertEquals("system.logger.one.a", records.get(0).getMessage(), "Unexpected message: ");
        Logger.getLogger("").setLevel(Level.INFO);
        Logger.getLogger("system.logger.one.a").finest("system.logger.one.a");
        records = test1.drain();
        assertEquals(0, records.size(), "Unexpected size for " + records.toString());

        Reference.reachabilityFence(system1a);
        Reference.reachabilityFence(system1b);

        System.out.println("\n[Case #2] Creating system logger: " + systemName2);
        Logger system2 = createSystemLogger(systemName2);
        System.out.println("    Creating app logger: " + appName2);
        Logger app2 = Logger.getLogger(appName2);
        System.out.println("    Configuring app logger...");
        TestHandler test2 = new TestHandler();
        app2.setLevel(Level.ALL);
        app2.setUseParentHandlers(false);
        app2.addHandler(test2);
        System.out.println("    Logging through system logger: " + systemName2);
        system2.finest(msg2);
        records = test2.drain();
        assertEquals(1, records.size(), "Unexpected size for " + records.toString());
        assertEquals(msg2, records.get(0).getMessage(), "Unexpected message: ");
        records = test1.drain();
        assertEquals(0, records.size(), "Unexpected size for " + records.toString());

        Reference.reachabilityFence(app2);
        Reference.reachabilityFence(system2);

        System.out.println("\n[Case #3] Creating app logger: " + appName3);
        Logger app3 = Logger.getLogger(appName3);
        System.out.println("    Configuring app logger...");
        TestHandler test3 = new TestHandler();
        app3.setLevel(Level.ALL);
        app3.setUseParentHandlers(false);
        app3.addHandler(test3);
        System.out.println("    Creating system logger: " + systemName3);
        Logger system3 = createSystemLogger(systemName3);
        System.out.println("    Logging through system logger: " + systemName3);
        system3.finest(msg3);
        records = test3.drain();
        assertEquals(1, records.size(), "Unexpected size for " + records.toString());
        assertEquals(msg3, records.get(0).getMessage(), "Unexpected message: ");
        records = test1.drain();
        assertEquals(0, records.size(), "Unexpected size for " + records.toString());

        Reference.reachabilityFence(app3);
        Reference.reachabilityFence(system3);
        System.gc();

    }

    @SuppressWarnings("deprecated")
    static void setPlatformLevel(PlatformLogger logger, PlatformLogger.Level level) {
        logger.setLevel(level);
    }

    public static void testSetPlatformLevel(String step) {
        System.out.println("\n*** Testing PlatformLogger.setLevel " + step);

        System.out.println("\n[Case #5] Creating app logger: " + step);
        // this should return named logger in the global context
        Logger foo = Logger.getLogger(step);
        foo.setLevel(Level.FINE);

        System.out.println("    Creating platform logger: " + step);
        PlatformLogger foo1 = PlatformLogger.getLogger(step);
        System.out.println("    Configuring platform logger...");
        setPlatformLevel(foo1, PlatformLogger.Level.INFO);

        System.out.println("    Checking levels...");
        assertEquals(foo.getName(), foo1.getName(), "Bad logger names");
         // both logger share the same config
        assertEquals(foo.getLevel(), Level.INFO, "Bad level for user logger");
        assertEquals(foo1.level(), PlatformLogger.Level.INFO,
                "Bad level for platform logger");

    }

    static void updateConfiguration(Properties props) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        props.store(baos, "");
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        LogManager.getLogManager().updateConfiguration(bais, (k) -> (o,n) -> n != null ? n : o);
    }

    static void readConfiguration(Properties props) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        props.store(baos, "");
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        LogManager.getLogManager().readConfiguration(bais);
    }

    // Tests that though two loggers exist, only one handler is created for the
    // pair when reading configuration.
    //
    public static void testUpdateConfiguration(String step) throws IOException {

        System.out.println("\n*** Testing LogManager.updateConfiguration " + step);

        final String name1a = "system.logger.one.a." + step;
        final String name1b = "system.logger.one.b." + step;
        final String msg1a = "logger name: " + name1a;
        final String msg1b = "logger name: " + name1b;
        List<LogRecord> records;

        TestHandler1.COUNT.set(0);
        TestHandler2.COUNT.set(0);
        Properties props = new Properties();
        props.setProperty(name1a+".handlers", TestHandler1.class.getName());
        updateConfiguration(props);
        assertEquals(0, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(0, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        System.out.println("\n[Case #4] Creating app logger: " + name1a);
        Logger app1a = Logger.getLogger(name1a);
        System.out.println("    Configuring app logger...");
        TestHandler test1 = new TestHandler();
        app1a.setLevel(Level.ALL);
        app1a.setUseParentHandlers(false);
        app1a.addHandler(test1);
        assertEquals(1, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(0, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        System.out.println("    Creating system logger: " + name1a);
        Logger system1a = createSystemLogger(name1a);
        assertEquals(Level.ALL, system1a.getLevel(), "Bad level for system logger " + name1a);
        System.out.println("    Logging through system logger: " + name1a);
        system1a.finest(msg1a);
        records = test1.drain();
        assertEquals(1, records.size(), "Unexpected size for " + records.toString());
        assertEquals(msg1a, records.get(0).getMessage(), "Unexpected message: ");
        records = test1.drain();
        assertEquals(0, records.size(), "Unexpected size for " + records.toString());

        assertEquals(1, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(0, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        props.setProperty(name1a+".handlers", TestHandler2.class.getName());
        updateConfiguration(props);

        assertEquals(1, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(1, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        updateConfiguration(props);

        assertEquals(1, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(1, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        readConfiguration(props);

        assertEquals(1, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        // readConfiguration reset handlers but does not recreate them
        assertEquals(1, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        updateConfiguration(props);

        assertEquals(1, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(1, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        LogManager.getLogManager().reset();
        updateConfiguration(props);

        assertEquals(1, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(2, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        props.setProperty(name1a+".handlers",
                TestHandler2.class.getName() + "," + TestHandler1.class.getName());
        updateConfiguration(props);

        assertEquals(2, TestHandler1.COUNT.get(), "Bad instance count for "
                + TestHandler1.class.getName());
        assertEquals(3, TestHandler2.COUNT.get(), "Bad instance count for "
                + TestHandler2.class.getName());

        Reference.reachabilityFence(app1a);
        Reference.reachabilityFence(system1a);

        LogManager.getLogManager().readConfiguration();
        System.gc();
    }



}
