/*
 * Copyright (c) 2015, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package jdk.internal.logger;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.ServiceLoader;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.Supplier;
import java.lang.System.LoggerFinder;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.lang.ref.WeakReference;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import sun.misc.InnocuousThread;
import sun.misc.VM;
import sun.util.logging.PlatformLogger;
import jdk.internal.logger.LazyLoggers.LazyLoggerAccessor;

/**
 * The BootstrapLogger class handles all the logic needed by Lazy Loggers
 * to delay the creation of System.Logger instances until the VM is booted.
 * By extension - it also contains the logic that will delay the creation
 * of JUL Loggers until the LogManager is initialized by the application, in
 * the common case where JUL is the default and there is no custom JUL
 * configuration.
 *
 * A BootstrapLogger instance is both a Logger and a
 * PlatformLogger.Bridge instance, which will put all Log messages in a queue
 * until the VM is booted.
 * Once the VM is booted, it obtain the real System.Logger instance from the
 * LoggerFinder and flushes the message to the queue.
 *
 * There are a few caveat:
 *  - the queue may not be flush until the next message is logged after
 *    the VM is booted
 *  - while the BootstrapLogger is active, the default implementation
 *    for all convenience methods is used
 *  - PlatformLogger.setLevel calls are ignored
 *
 *
 */
public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
        PlatformLogger.ConfigurableBridge {

    // We use the BootstrapExecutors class to submit delayed messages
    // to an independent InnocuousThread which will ensure that
    // delayed log events will be clearly identified as messages that have
    // been delayed during the boot sequence.
    private static class BootstrapExecutors implements ThreadFactory {

        // Maybe that should be made configurable with system properties.
        static final long KEEP_EXECUTOR_ALIVE_SECONDS = 30;

        // The BootstrapMessageLoggerTask is a Runnable which keeps
        // a hard ref to the ExecutorService that owns it.
        // This ensure that the ExecutorService is not gc'ed until the thread
        // has stopped running.
        private static class BootstrapMessageLoggerTask implements Runnable {
            ExecutorService owner;
            Runnable run;
            public BootstrapMessageLoggerTask(ExecutorService owner, Runnable r) {
                this.owner = owner;
                this.run = r;
            }
            @Override
            public void run() {
                try {
                    run.run();
                } finally {
                    owner = null; // allow the ExecutorService to be gced.
                }
            }
        }

        private static volatile WeakReference<ExecutorService> executorRef;
        private static ExecutorService getExecutor() {
            WeakReference<ExecutorService> ref = executorRef;
            ExecutorService executor = ref == null ? null : ref.get();
            if (executor != null) return executor;
            synchronized (BootstrapExecutors.class) {
                ref = executorRef;
                executor = ref == null ? null : ref.get();
                if (executor == null) {
                    executor = new ThreadPoolExecutor(0, 1,
                            KEEP_EXECUTOR_ALIVE_SECONDS, TimeUnit.SECONDS,
                            new LinkedBlockingQueue<>(), new BootstrapExecutors());
                }
                // The executor service will be elligible for gc
                // KEEP_EXECUTOR_ALIVE_SECONDS seconds (30s)
                // after the execution of its last pending task.
                executorRef = new WeakReference<>(executor);
                return executorRef.get();
            }
        }

        @Override
        public Thread newThread(Runnable r) {
            ExecutorService owner = getExecutor();
            Thread thread = AccessController.doPrivileged(new PrivilegedAction<Thread>() {
                @Override
                public Thread run() {
                    Thread t = new InnocuousThread(new BootstrapMessageLoggerTask(owner, r));
                    t.setName("BootstrapMessageLoggerTask-"+t.getName());
                    return t;
                }
            }, null, new RuntimePermission("enableContextClassLoaderOverride"));
            thread.setDaemon(true);
            return thread;
        }

        static void submit(Runnable r) {
            getExecutor().execute(r);
        }

        // This is used by tests.
        static void join(Runnable r) {
            try {
                getExecutor().submit(r).get();
            } catch (InterruptedException | ExecutionException ex) {
                // should not happen
                throw new RuntimeException(ex);
            }
        }

        // This is used by tests.
        static void awaitPendingTasks() {
            WeakReference<ExecutorService> ref = executorRef;
            ExecutorService executor = ref == null ? null : ref.get();
            if (ref == null) {
                synchronized(BootstrapExecutors.class) {
                    ref = executorRef;
                    executor = ref == null ? null : ref.get();
                }
            }
            if (executor != null) {
                // since our executor uses a FIFO and has a single thread
                // then awaiting the execution of its pending tasks can be done
                // simply by registering a new task and waiting until it
                // completes. This of course would not work if we were using
                // several threads, but we don't.
                join(()->{});
            }
        }

        // This is used by tests.
        static boolean isAlive() {
            WeakReference<ExecutorService> ref = executorRef;
            ExecutorService executor = ref == null ? null : ref.get();
            if (executor != null) return true;
            synchronized (BootstrapExecutors.class) {
                ref = executorRef;
                executor = ref == null ? null : ref.get();
                return executor != null;
            }
        }

        // The pending log event queue. The first event is the head, and
        // new events are added at the tail
        static LogEvent head, tail;

        static void enqueue(LogEvent event) {
            if (event.next != null) return;
            synchronized (BootstrapExecutors.class) {
                if (event.next != null) return;
                event.next = event;
                if (tail == null) {
                    head = tail = event;
                } else {
                    tail.next = event;
                    tail = event;
                }
            }
        }

        static void flush() {
            LogEvent event;
            // drain the whole queue
            synchronized(BootstrapExecutors.class) {
                event = head;
                head = tail = null;
            }
            while(event != null) {
                LogEvent.log(event);
                synchronized(BootstrapExecutors.class) {
                    LogEvent prev = event;
                    event = (event.next == event ? null : event.next);
                    prev.next = null;
                }
            }
        }
    }

    // The accessor in which this logger is temporarily set.
    final LazyLoggerAccessor holder;

    BootstrapLogger(LazyLoggerAccessor holder) {
        this.holder = holder;
    }

    // Temporary data object storing log events
    // It would be nice to use a Consumer<Logger> instead of a LogEvent.
    // This way we could simply do things like:
    //    push((logger) -> logger.log(level, msg));
    // Unfortunately, if we come to here it means we are in the bootsraping
    // phase where using lambdas is not safe yet - so we have to use a
    // a data object instead...
    //
    static final class LogEvent {
        // only one of these two levels should be non null
        final Level level;
        final PlatformLogger.Level platformLevel;
        final BootstrapLogger bootstrap;

        final ResourceBundle bundle;
        final String msg;
        final Throwable thrown;
        final Object[] params;
        final Supplier<String> msgSupplier;
        final String sourceClass;
        final String sourceMethod;
        final long timeMillis;
        final long nanoAdjustment;

        // because logging a message may entail calling toString() on
        // the parameters etc... we need to store the context of the
        // caller who logged the message - so that we can reuse it when
        // we finally log the message.
        final AccessControlContext acc;

        // The next event in the queue
        LogEvent next;

        private LogEvent(BootstrapLogger bootstrap, Level level,
                ResourceBundle bundle, String msg,
                Throwable thrown, Object[] params) {
            this.acc = AccessController.getContext();
            this.timeMillis = System.currentTimeMillis();
            this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
            this.level = level;
            this.platformLevel = null;
            this.bundle = bundle;
            this.msg = msg;
            this.msgSupplier = null;
            this.thrown = thrown;
            this.params = params;
            this.sourceClass = null;
            this.sourceMethod = null;
            this.bootstrap = bootstrap;
        }

        private LogEvent(BootstrapLogger bootstrap, Level level,
                Supplier<String> msgSupplier,
                Throwable thrown, Object[] params) {
            this.acc = AccessController.getContext();
            this.timeMillis = System.currentTimeMillis();
            this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
            this.level = level;
            this.platformLevel = null;
            this.bundle = null;
            this.msg = null;
            this.msgSupplier = msgSupplier;
            this.thrown = thrown;
            this.params = params;
            this.sourceClass = null;
            this.sourceMethod = null;
            this.bootstrap = bootstrap;
        }

        private LogEvent(BootstrapLogger bootstrap,
                PlatformLogger.Level platformLevel,
                String sourceClass, String sourceMethod,
                ResourceBundle bundle, String msg,
                Throwable thrown, Object[] params) {
            this.acc = AccessController.getContext();
            this.timeMillis = System.currentTimeMillis();
            this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
            this.level = null;
            this.platformLevel = platformLevel;
            this.bundle = bundle;
            this.msg = msg;
            this.msgSupplier = null;
            this.thrown = thrown;
            this.params = params;
            this.sourceClass = sourceClass;
            this.sourceMethod = sourceMethod;
            this.bootstrap = bootstrap;
        }

        private LogEvent(BootstrapLogger bootstrap,
                PlatformLogger.Level platformLevel,
                String sourceClass, String sourceMethod,
                Supplier<String> msgSupplier,
                Throwable thrown, Object[] params) {
            this.acc = AccessController.getContext();
            this.timeMillis = System.currentTimeMillis();
            this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
            this.level = null;
            this.platformLevel = platformLevel;
            this.bundle = null;
            this.msg = null;
            this.msgSupplier = msgSupplier;
            this.thrown = thrown;
            this.params = params;
            this.sourceClass = sourceClass;
            this.sourceMethod = sourceMethod;
            this.bootstrap = bootstrap;
        }

        // Log this message in the given logger. Do not call directly.
        // Use LogEvent.log(LogEvent, logger) instead.
        private void log(Logger logger) {
            assert platformLevel == null && level != null;
            //new Exception("logging delayed message").printStackTrace();
            if (msgSupplier != null) {
                if (thrown != null) {
                    logger.log(level, msgSupplier, thrown);
                } else {
                    logger.log(level, msgSupplier);
                }
            } else {
                // BootstrapLoggers are never localized so we can safely
                // use the method that takes a ResourceBundle parameter
                // even when that resource bundle is null.
                if (thrown != null) {
                    logger.log(level, bundle, msg, thrown);
                } else {
                    logger.log(level, bundle, msg, params);
                }
            }
        }

        // Log this message in the given logger.  Do not call directly.
        // Use LogEvent.doLog(LogEvent, logger) instead.
        private void log(PlatformLogger.Bridge logger) {
            assert platformLevel != null && level == null;
            if (sourceClass == null) {
                if (msgSupplier != null) {
                    if (thrown != null) {
                        logger.log(platformLevel, thrown, msgSupplier);
                    } else {
                        logger.log(platformLevel, msgSupplier);
                    }
                } else {
                    // BootstrapLoggers are never localized so we can safely
                    // use the method that takes a ResourceBundle parameter
                    // even when that resource bundle is null.
                    if (thrown != null) {
                        logger.logrb(platformLevel, bundle, msg, thrown);
                    } else {
                        logger.logrb(platformLevel, bundle, msg, params);
                    }
                }
            } else {
                if (msgSupplier != null) {
                    if (thrown != null) {
                        logger.logp(platformLevel, sourceClass, sourceMethod, thrown, msgSupplier);
                    } else {
                        logger.logp(platformLevel, sourceClass, sourceMethod, msgSupplier);
                    }
                } else {
                    // BootstrapLoggers are never localized so we can safely
                    // use the method that takes a ResourceBundle parameter
                    // even when that resource bundle is null.
                    if (thrown != null) {
                        logger.logrb(platformLevel, sourceClass, sourceMethod, bundle, msg, thrown);
                    } else {
                        logger.logrb(platformLevel, sourceClass, sourceMethod, bundle, msg, params);
                    }
                }
            }
        }

        // non default methods from Logger interface
        static LogEvent valueOf(BootstrapLogger bootstrap, Level level,
                ResourceBundle bundle, String key, Throwable thrown) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level), bundle, key,
                                thrown, null);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, Level level,
                ResourceBundle bundle, String format, Object[] params) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level), bundle, format,
                                null, params);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, Level level,
                                Supplier<String> msgSupplier, Throwable thrown) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                    Objects.requireNonNull(level),
                    Objects.requireNonNull(msgSupplier), thrown, null);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, Level level,
                                Supplier<String> msgSupplier) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level),
                                Objects.requireNonNull(msgSupplier), null, null);
        }
        static void log(LogEvent log, Logger logger) {
            final SecurityManager sm = System.getSecurityManager();
            // not sure we can actually use lambda here. We may need to create
            // an anonymous class. Although if we reach here, then it means
            // the VM is booted.
            if (sm == null || log.acc == null) {
                BootstrapExecutors.submit(() -> log.log(logger));
            } else {
                BootstrapExecutors.submit(() ->
                    AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                        log.log(logger); return null;
                    }, log.acc));
            }
        }

        // non default methods from PlatformLogger.Bridge interface
        static LogEvent valueOf(BootstrapLogger bootstrap,
                                PlatformLogger.Level level, String msg) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level), null, null, null,
                                msg, null, null);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, PlatformLogger.Level level,
                                String msg, Throwable thrown) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                    Objects.requireNonNull(level), null, null, null, msg, thrown, null);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, PlatformLogger.Level level,
                                String msg, Object[] params) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                    Objects.requireNonNull(level), null, null, null, msg, null, params);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, PlatformLogger.Level level,
                                Supplier<String> msgSupplier) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                    Objects.requireNonNull(level), null, null, msgSupplier, null, null);
        }
        static LogEvent vaueOf(BootstrapLogger bootstrap, PlatformLogger.Level level,
                               Supplier<String> msgSupplier,
                               Throwable thrown) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level), null, null,
                                msgSupplier, thrown, null);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, PlatformLogger.Level level,
                                String sourceClass, String sourceMethod,
                                ResourceBundle bundle, String msg, Object[] params) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level), sourceClass,
                                sourceMethod, bundle, msg, null, params);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, PlatformLogger.Level level,
                                String sourceClass, String sourceMethod,
                                ResourceBundle bundle, String msg, Throwable thrown) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level), sourceClass,
                                sourceMethod, bundle, msg, thrown, null);
        }
        static LogEvent valueOf(BootstrapLogger bootstrap, PlatformLogger.Level level,
                                String sourceClass, String sourceMethod,
                                Supplier<String> msgSupplier, Throwable thrown) {
            return new LogEvent(Objects.requireNonNull(bootstrap),
                                Objects.requireNonNull(level), sourceClass,
                                sourceMethod, msgSupplier, thrown, null);
        }
        static void log(LogEvent log, PlatformLogger.Bridge logger) {
            final SecurityManager sm = System.getSecurityManager();
            if (sm == null || log.acc == null) {
                log.log(logger);
            } else {
                // not sure we can actually use lambda here. We may need to create
                // an anonymous class. Although if we reach here, then it means
                // the VM is booted.
                AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                    log.log(logger); return null;
                }, log.acc);
            }
        }

        static void log(LogEvent event) {
            event.bootstrap.flush(event);
        }

    }

    // Push a log event at the end of the pending LogEvent queue.
    void push(LogEvent log) {
        BootstrapExecutors.enqueue(log);
        // if the queue has been flushed just before we entered
        // the synchronized block we need to flush it again.
        checkBootstrapping();
    }

    // Flushes the queue of pending LogEvents to the logger.
    void flush(LogEvent event) {
        assert event.bootstrap == this;
        if (event.platformLevel != null) {
            PlatformLogger.Bridge concrete = holder.getConcretePlatformLogger(this);
            LogEvent.log(event, concrete);
        } else {
            Logger concrete = holder.getConcreteLogger(this);
            LogEvent.log(event, concrete);
        }
    }

    /**
     * The name of this logger. This is the name of the actual logger for which
     * this logger acts as a temporary proxy.
     * @return The logger name.
     */
    @Override
    public String getName() {
        return holder.name;
    }

    /**
     * Check whether the VM is still bootstrapping, and if not, arranges
     * for this logger's holder to create the real logger and flush the
     * pending event queue.
     * @return true if the VM is still bootstrapping.
     */
    boolean checkBootstrapping() {
        if (isBooted()) {
            BootstrapExecutors.flush();
            return false;
        }
        return true;
    }

    // ----------------------------------
    // Methods from Logger
    // ----------------------------------

    @Override
    public boolean isLoggable(Level level) {
        if (checkBootstrapping()) {
            return level.getSeverity() >= Level.INFO.getSeverity();
        } else {
            final Logger spi = holder.wrapped();
            return spi.isLoggable(level);
        }
    }

    @Override
    public void log(Level level, ResourceBundle bundle, String key, Throwable thrown) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, bundle, key, thrown));
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, bundle, key, thrown);
        }
    }

    @Override
    public void log(Level level, ResourceBundle bundle, String format, Object... params) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, bundle, format, params));
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, bundle, format, params);
        }
    }

    @Override
    public void log(Level level, String msg, Throwable thrown) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, null, msg, thrown));
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, msg, thrown);
        }
    }

    @Override
    public void log(Level level, String format, Object... params) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, null, format, params));
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, format, params);
        }
    }

    @Override
    public void log(Level level, Supplier<String> msgSupplier) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, msgSupplier));
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, msgSupplier);
        }
    }

    @Override
    public void log(Level level, Object obj) {
        if (checkBootstrapping()) {
            Logger.super.log(level, obj);
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, obj);
        }
    }

    @Override
    public void log(Level level, String msg) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, null, msg, (Object[])null));
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, msg);
        }
    }

    @Override
    public void log(Level level, Supplier<String> msgSupplier, Throwable thrown) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, msgSupplier, thrown));
        } else {
            final Logger spi = holder.wrapped();
            spi.log(level, msgSupplier, thrown);
        }
    }

    // ----------------------------------
    // Methods from PlatformLogger.Bridge
    // ----------------------------------

    @Override
    public boolean isLoggable(PlatformLogger.Level level) {
        if (checkBootstrapping()) {
            return level.intValue() >= PlatformLogger.Level.INFO.intValue();
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            return spi.isLoggable(level);
        }
    }

    @Override
    public boolean isEnabled() {
        if (checkBootstrapping()) {
            return true;
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            return spi.isEnabled();
        }
    }

    @Override
    public void log(PlatformLogger.Level level, String msg) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, msg));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.log(level, msg);
        }
    }

    @Override
    public void log(PlatformLogger.Level level, String msg, Throwable thrown) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, msg, thrown));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.log(level, msg, thrown);
        }
    }

    @Override
    public void log(PlatformLogger.Level level, String msg, Object... params) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, msg, params));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.log(level, msg, params);
        }
    }

    @Override
    public void log(PlatformLogger.Level level, Supplier<String> msgSupplier) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, msgSupplier));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.log(level, msgSupplier);
        }
    }

    @Override
    public void log(PlatformLogger.Level level, Throwable thrown,
            Supplier<String> msgSupplier) {
        if (checkBootstrapping()) {
            push(LogEvent.vaueOf(this, level, msgSupplier, thrown));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.log(level, thrown, msgSupplier);
        }
    }

    @Override
    public void logp(PlatformLogger.Level level, String sourceClass,
            String sourceMethod, String msg) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, sourceClass, sourceMethod, null,
                    msg, (Object[])null));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logp(level, sourceClass, sourceMethod, msg);
        }
    }

    @Override
    public void logp(PlatformLogger.Level level, String sourceClass,
            String sourceMethod, Supplier<String> msgSupplier) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, sourceClass, sourceMethod, msgSupplier, null));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logp(level, sourceClass, sourceMethod, msgSupplier);
        }
    }

    @Override
    public void logp(PlatformLogger.Level level, String sourceClass,
            String sourceMethod, String msg, Object... params) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, sourceClass, sourceMethod, null, msg, params));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logp(level, sourceClass, sourceMethod, msg, params);
        }
    }

    @Override
    public void logp(PlatformLogger.Level level, String sourceClass,
            String sourceMethod, String msg, Throwable thrown) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, sourceClass, sourceMethod, null, msg, thrown));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logp(level, sourceClass, sourceMethod, msg, thrown);
        }
    }

    @Override
    public void logp(PlatformLogger.Level level, String sourceClass,
            String sourceMethod, Throwable thrown, Supplier<String> msgSupplier) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, sourceClass, sourceMethod, msgSupplier, thrown));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logp(level, sourceClass, sourceMethod, thrown, msgSupplier);
        }
    }

    @Override
    public void logrb(PlatformLogger.Level level, String sourceClass,
            String sourceMethod, ResourceBundle bundle, String msg, Object... params) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, sourceClass, sourceMethod, bundle, msg, params));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logrb(level, sourceClass, sourceMethod, bundle, msg, params);
        }
    }

    @Override
    public void logrb(PlatformLogger.Level level, String sourceClass,
            String sourceMethod, ResourceBundle bundle, String msg, Throwable thrown) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, sourceClass, sourceMethod, bundle, msg, thrown));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logrb(level, sourceClass, sourceMethod, bundle, msg, thrown);
        }
    }

    @Override
    public void logrb(PlatformLogger.Level level, ResourceBundle bundle,
            String msg, Object... params) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, null, null, bundle, msg, params));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logrb(level, bundle, msg, params);
        }
    }

    @Override
    public void logrb(PlatformLogger.Level level, ResourceBundle bundle, String msg, Throwable thrown) {
        if (checkBootstrapping()) {
            push(LogEvent.valueOf(this, level, null, null, bundle, msg, thrown));
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            spi.logrb(level, bundle, msg, thrown);
        }
    }

    @Override
    public LoggerConfiguration getLoggerConfiguration() {
        if (checkBootstrapping()) {
            // This practically means that PlatformLogger.setLevel()
            // calls will be ignored if the VM is still bootstrapping. We could
            // attempt to fix that but is it worth it?
            return PlatformLogger.ConfigurableBridge.super.getLoggerConfiguration();
        } else {
            final PlatformLogger.Bridge spi = holder.platform();
            return PlatformLogger.ConfigurableBridge.getLoggerConfiguration(spi);
        }
    }

    // This BooleanSupplier is a hook for tests - so that we can simulate
    // what would happen before the VM is booted.
    private static volatile BooleanSupplier isBooted;
    public static boolean isBooted() {
        if (isBooted != null) return isBooted.getAsBoolean();
        else return VM.isBooted();
    }

    // A bit of black magic. We try to find out the nature of the logging
    // backend without actually loading it.
    private static enum LoggingBackend {
        // There is no LoggerFinder and JUL is not present
        NONE(true),

        // There is no LoggerFinder, but we have found a
        // JdkLoggerFinder installed (which means JUL is present),
        // and we haven't found any custom configuration for JUL.
        // Until LogManager is initialized we can use a simple console
        // logger.
        JUL_DEFAULT(false),

        // Same as above, except that we have found a custom configuration
        // for JUL. We cannot use the simple console logger in this case.
        JUL_WITH_CONFIG(true),

        // We have found a custom LoggerFinder.
        CUSTOM(true);

        final boolean useLoggerFinder;
        private LoggingBackend(boolean useLoggerFinder) {
            this.useLoggerFinder = useLoggerFinder;
        }
    };

    // The purpose of this class is to delay the initialization of
    // the detectedBackend field until it is actually read.
    // We do not want this field to get initialized if VM.isBooted() is false.
    private static final class DetectBackend {
        static final LoggingBackend detectedBackend;
        static {
            detectedBackend = AccessController.doPrivileged(new PrivilegedAction<LoggingBackend>() {
                    @Override
                    public LoggingBackend run() {
                        final Iterator<LoggerFinder> iterator =
                            ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader())
                            .iterator();
                        if (iterator.hasNext()) {
                            return LoggingBackend.CUSTOM; // Custom Logger Provider is registered
                        }
                        // No custom logger provider: we will be using the default
                        // backend.
                        final Iterator<DefaultLoggerFinder> iterator2 =
                            ServiceLoader.loadInstalled(DefaultLoggerFinder.class)
                            .iterator();
                        if (iterator2.hasNext()) {
                            // LoggingProviderImpl is registered. The default
                            // implementation is java.util.logging
                            String cname = System.getProperty("java.util.logging.config.class");
                            String fname = System.getProperty("java.util.logging.config.file");
                            return (cname != null || fname != null)
                                ? LoggingBackend.JUL_WITH_CONFIG
                                : LoggingBackend.JUL_DEFAULT;
                        } else {
                            // SimpleLogger is used
                            return LoggingBackend.NONE;
                        }
                    }
                });

        }
    }

    // We will use temporary SimpleConsoleLoggers if
    // the logging backend is JUL, there is no custom config,
    // and the LogManager has not been initialized yet.
    private static  boolean useTemporaryLoggers() {
        // being paranoid: this should already have been checked
        if (!isBooted()) return true;
        return DetectBackend.detectedBackend == LoggingBackend.JUL_DEFAULT
                && !logManagerConfigured;
    }

    // We will use lazy loggers if:
    //    - the VM is not yet booted
    //    - the logging backend is a custom backend
    //    - the logging backend is JUL, there is no custom config,
    //      and the LogManager has not been initialized yet.
    public static synchronized boolean useLazyLoggers() {
        return !BootstrapLogger.isBooted()
                || DetectBackend.detectedBackend == LoggingBackend.CUSTOM
                || useTemporaryLoggers();
    }

    // Called by LazyLoggerAccessor. This method will determine whether
    // to create a BootstrapLogger (if the VM is not yet booted),
    // a SimpleConsoleLogger (if JUL is the default backend and there
    // is no custom JUL configuration and LogManager is not yet initialized),
    // or a logger returned by the loaded LoggerFinder (all other cases).
    static Logger getLogger(LazyLoggerAccessor accessor) {
        if (!BootstrapLogger.isBooted()) {
            return new BootstrapLogger(accessor);
        } else {
            boolean temporary = useTemporaryLoggers();
            if (temporary) {
                // JUL is the default backend, there is no custom configuration,
                // LogManager has not been used.
                synchronized(BootstrapLogger.class) {
                    if (useTemporaryLoggers()) {
                        return makeTemporaryLogger(accessor);
                    }
                }
            }
            // Already booted. Return the real logger.
            return accessor.createLogger();
        }
    }


    // If the backend is JUL, and there is no custom configuration, and
    // nobody has attempted to call LogManager.getLogManager() yet, then
    // we can temporarily substitute JUL Logger with SimpleConsoleLoggers,
    // which avoids the cost of actually loading up the LogManager...
    // The TemporaryLoggers class has the logic to create such temporary
    // loggers, and to possibly replace them with real JUL loggers if
    // someone calls LogManager.getLogManager().
    static final class TemporaryLoggers implements
            Function<LazyLoggerAccessor, SimpleConsoleLogger> {

        // all accesses must be synchronized on the outer BootstrapLogger.class
        final Map<LazyLoggerAccessor, SimpleConsoleLogger> temporaryLoggers =
                new HashMap<>();

        // all accesses must be synchronized on the outer BootstrapLogger.class
        // The temporaryLoggers map will be cleared when LogManager is initialized.
        boolean cleared;

        @Override
        // all accesses must be synchronized on the outer BootstrapLogger.class
        public SimpleConsoleLogger apply(LazyLoggerAccessor t) {
            if (cleared) throw new IllegalStateException("LoggerFinder already initialized");
            return SimpleConsoleLogger.makeSimpleLogger(t.getLoggerName(), true);
        }

        // all accesses must be synchronized on the outer BootstrapLogger.class
        SimpleConsoleLogger get(LazyLoggerAccessor a) {
            if (cleared) throw new IllegalStateException("LoggerFinder already initialized");
            return temporaryLoggers.computeIfAbsent(a, this);
        }

        // all accesses must be synchronized on the outer BootstrapLogger.class
        Map<LazyLoggerAccessor, SimpleConsoleLogger> drainTemporaryLoggers() {
            if (temporaryLoggers.isEmpty()) return null;
            if (cleared) throw new IllegalStateException("LoggerFinder already initialized");
            final Map<LazyLoggerAccessor, SimpleConsoleLogger> accessors = new HashMap<>(temporaryLoggers);
            temporaryLoggers.clear();
            cleared = true;
            return accessors;
        }

        static void resetTemporaryLoggers(Map<LazyLoggerAccessor, SimpleConsoleLogger> accessors) {
            // When the backend is JUL we want to force the creation of
            // JUL loggers here: some tests are expecting that the
            // PlatformLogger will create JUL loggers as soon as the
            // LogManager is initialized.
            //
            // If the backend is not JUL then we can delay the re-creation
            // of the wrapped logger until they are next accessed.
            //
            final LoggingBackend detectedBackend = DetectBackend.detectedBackend;
            final boolean lazy = detectedBackend != LoggingBackend.JUL_DEFAULT
                    && detectedBackend != LoggingBackend.JUL_WITH_CONFIG;
            for (Map.Entry<LazyLoggerAccessor, SimpleConsoleLogger> a : accessors.entrySet()) {
                a.getKey().release(a.getValue(), !lazy);
            }
        }

        // all accesses must be synchronized on the outer BootstrapLogger.class
        static final TemporaryLoggers INSTANCE = new TemporaryLoggers();
    }

    static synchronized Logger makeTemporaryLogger(LazyLoggerAccessor a) {
        // accesses to TemporaryLoggers is synchronized on BootstrapLogger.class
        return TemporaryLoggers.INSTANCE.get(a);
    }

    private static volatile boolean logManagerConfigured;

    private static synchronized Map<LazyLoggerAccessor, SimpleConsoleLogger>
         releaseTemporaryLoggers() {
        // first check whether there's a chance that we have used
        // temporary loggers; Will be false if logManagerConfigured is already
        // true.
        final boolean clearTemporaryLoggers = useTemporaryLoggers();

        // then sets the flag that tells that the log manager is configured
        logManagerConfigured = true;

        // finally replace all temporary loggers by real JUL loggers
        if (clearTemporaryLoggers) {
            // accesses to TemporaryLoggers is synchronized on BootstrapLogger.class
            return TemporaryLoggers.INSTANCE.drainTemporaryLoggers();
        } else {
            return null;
        }
    }

    public static void redirectTemporaryLoggers() {
        // This call is synchronized on BootstrapLogger.class.
        final Map<LazyLoggerAccessor, SimpleConsoleLogger> accessors =
                releaseTemporaryLoggers();

        // We will now reset the logger accessors, triggering the
        // (possibly lazy) replacement of any temporary logger by the
        // real logger returned from the loaded LoggerFinder.
        if (accessors != null) {
            TemporaryLoggers.resetTemporaryLoggers(accessors);
        }

        BootstrapExecutors.flush();
    }

    // Hook for tests which need to wait until pending messages
    // are processed.
    static void awaitPendingTasks() {
        BootstrapExecutors.awaitPendingTasks();
    }
    static boolean isAlive() {
        return BootstrapExecutors.isAlive();
    }

}
