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

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.async.AsyncLoggerContext;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.apache.logging.log4j.core.util.Constants;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.TimeUnit;
import java.util.logging.FileHandler;
import java.util.logging.Level;

/**
 * Benchmarks Log4j 2, Log4j 1, Logback and JUL using the ERROR level which is enabled for this test.
 * The configuration for each writes to disk.
 */
// HOW TO RUN THIS TEST
// java -jar target/benchmarks.jar ".*FileAppenderThrowableBenchmark.*" -f 1 -i 10 -wi 20 -bm sample -tu ns
@State(Scope.Benchmark)
@Threads(1)
@Fork(1)
@Warmup(iterations = 3, time = 3)
@Measurement(iterations = 3, time = 3)
public class FileAppenderThrowableBenchmark {
    static {
        // log4j2
        System.setProperty("log4j2.is.webapp", "false");
        System.setProperty("log4j.configurationFile", "log4j2-perf-file-throwable.xml");
        // log4j 1.2
        System.setProperty("log4j.configuration", "log4j12-perf-file-throwable.xml");
        // logback
        System.setProperty("logback.configurationFile", "logback-perf-file-throwable.xml");
    }

    private static final Throwable THROWABLE = getSimpleThrowable();
    private static final Throwable COMPLEX_THROWABLE = getComplexThrowable();

    @SuppressWarnings("unused") // Set by JMH
    @Param
    private LoggingConfiguration loggingConfiguration;

    private static Throwable getSimpleThrowable() {
        return new IllegalStateException("Test Throwable");
    }

    interface ThrowableHelper {
        void action();
    }

    // Used to create a deeper stack with many different classes
    // This makes the ThrowableProxy Map<String, CacheEntry> cache
    // perform more closely to real applications.
    interface TestIface0 extends ThrowableHelper {}
    interface TestIface1 extends ThrowableHelper {}
    interface TestIface2 extends ThrowableHelper {}
    interface TestIface3 extends ThrowableHelper {}
    interface TestIface4 extends ThrowableHelper {}
    interface TestIface5 extends ThrowableHelper {}
    interface TestIface6 extends ThrowableHelper {}
    interface TestIface7 extends ThrowableHelper {}
    interface TestIface8 extends ThrowableHelper {}
    interface TestIface9 extends ThrowableHelper {}
    interface TestIface10 extends ThrowableHelper {}
    interface TestIface11 extends ThrowableHelper {}
    interface TestIface12 extends ThrowableHelper {}
    interface TestIface13 extends ThrowableHelper {}
    interface TestIface14 extends ThrowableHelper {}
    interface TestIface15 extends ThrowableHelper {}
    interface TestIface16 extends ThrowableHelper {}
    interface TestIface17 extends ThrowableHelper {}
    interface TestIface18 extends ThrowableHelper {}
    interface TestIface19 extends ThrowableHelper {}
    interface TestIface20 extends ThrowableHelper {}
    interface TestIface21 extends ThrowableHelper {}
    interface TestIface22 extends ThrowableHelper {}
    interface TestIface23 extends ThrowableHelper {}
    interface TestIface24 extends ThrowableHelper {}
    interface TestIface25 extends ThrowableHelper {}
    interface TestIface26 extends ThrowableHelper {}
    interface TestIface27 extends ThrowableHelper {}
    interface TestIface28 extends ThrowableHelper {}
    interface TestIface29 extends ThrowableHelper {}
    interface TestIface30 extends ThrowableHelper {}

    private static Throwable getComplexThrowable() {
        ThrowableHelper helper = () -> {
            throw new IllegalStateException("Test Throwable");
        };
        try {
            for (int i = 0; i < 31; i++) {
                final ThrowableHelper delegate = helper;
                helper = (ThrowableHelper) Proxy.newProxyInstance(
                        FileAppenderThrowableBenchmark.class.getClassLoader(),
                        new Class<?>[]{Class.forName(FileAppenderThrowableBenchmark.class.getName() + "$TestIface" + (i % 31))},
                        (proxy, method, args) -> {
                            try {
                                return method.invoke(delegate, args);
                            } catch (InvocationTargetException e) {
                                throw e.getCause();
                            }
                        });
            }
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("Failed to create stack", e);
        }
        try {
            helper.action();
        } catch (IllegalStateException e) {
            return e;
        }
        throw new IllegalStateException("Failed to create throwable");
    }


    @Setup
    public void setUp() throws Exception {
        deleteLogFiles();
        loggingConfiguration.setUp();
    }

    @TearDown
    public void tearDown() throws Exception{
        loggingConfiguration.tearDown();
        deleteLogFiles();
    }

    private void deleteLogFiles() {
        final File logbackFile = new File("target/testlogback.log");
        logbackFile.delete();
        final File log4jFile = new File ("target/testlog4j.log");
        log4jFile.delete();
        final File log4jRandomFile = new File ("target/extended-exception.log");
        log4jRandomFile.delete();
        final File log4j2File = new File ("target/simple-exception.log");
        log4j2File.delete();
        final File julFile = new File("target/testJulLog.log");
        julFile.delete();
    }

    @SuppressWarnings("unused") // Used by JMH
    public enum LoggingConfiguration {
        LOG4J2_EXTENDED_THROWABLE() {
            Logger logger;
            @Override
            void setUp() throws Exception {
                logger = LogManager.getLogger("RAFExtendedException");
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        LOG4J2_EXTENDED_THROWABLE_ASYNC() {
            Logger logger;
            @Override
            void setUp() throws Exception {
                System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR,
                        AsyncLoggerContextSelector.class.getName());
                logger = LogManager.getLogger("RAFExtendedException");
                if (!AsyncLoggerContext.class.equals(LogManager.getContext(false).getClass())) {
                    throw new IllegalStateException("Expected an AsyncLoggerContext");
                }
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        LOG4J2_EXTENDED_THROWABLE_ASYNC_CONFIG() {
            Logger logger;
            @Override
            void setUp() throws Exception {
                logger = LogManager.getLogger("async.RAFExtendedException");
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        LOG4J2_THROWABLE() {
            Logger logger;
            @Override
            void setUp() throws Exception {
                logger = LogManager.getLogger("RAFSimpleException");
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        LOG4J2_THROWABLE_ASYNC() {
            Logger logger;
            @Override
            void setUp() throws Exception {
                System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR,
                        AsyncLoggerContextSelector.class.getName());
                logger = LogManager.getLogger("RAFSimpleException");
                if (!AsyncLoggerContext.class.equals(LogManager.getContext(false).getClass())) {
                    throw new IllegalStateException("Expected an AsyncLoggerContext");
                }
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        LOG4J2_THROWABLE_ASYNC_CONFIG() {
            Logger logger;
            @Override
            void setUp() throws Exception {
                logger = LogManager.getLogger("async.RAFSimpleException");
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        LOG4J1() {
            org.apache.log4j.Logger logger;
            @Override
            void setUp() throws Exception {
                logger = org.apache.log4j.Logger.getLogger(FileAppenderThrowableBenchmark.class);
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        LOGBACK() {
            org.slf4j.Logger logger;

            @Override
            void setUp() throws Exception {
                logger = LoggerFactory.getLogger(FileAppenderThrowableBenchmark.class);
            }

            @Override
            void tearDown() throws Exception {

            }

            @Override
            void log(String message, Throwable throwable) {
                logger.error(message, throwable);
            }
        },
        JUL() {
            private FileHandler julFileHandler;
            private java.util.logging.Logger logger;

            @Override
            void setUp() throws Exception {
                julFileHandler = new FileHandler("target/testJulLog.log");
                logger = java.util.logging.Logger.getLogger(getClass().getName());
                logger.setUseParentHandlers(false);
                logger.addHandler(julFileHandler);
                logger.setLevel(Level.ALL);
            }

            @Override
            void tearDown() throws Exception {
                julFileHandler.close();
            }

            @Override
            void log(String message, Throwable throwable) {
                // must specify sourceClass or JUL will look it up by walking the stack trace!
                logger.logp(Level.SEVERE, FileAppenderThrowableBenchmark.class.getName(), "param1JulFile", message, throwable);
            }
        };

        abstract void setUp() throws Exception;

        abstract void tearDown() throws Exception;

        abstract void log(String message, Throwable throwable);
    }

    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.SECONDS)
    @Benchmark
    public void simpleThrowable() {
        loggingConfiguration.log("Caught an exception", THROWABLE);
    }

    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.SECONDS)
    @Benchmark
    public void complexThrowable() {
        loggingConfiguration.log("Caught an exception", COMPLEX_THROWABLE);
    }
}
