/*
 * 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 java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext.ContextStack;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.util.StringMap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;

/**
 * Compares Log4j2 with Logback PatternLayout performance.
 */
// ============================== HOW TO RUN THIS TEST: ====================================
//
// single thread:
// java -jar log4j-perf/target/benchmarks.jar ".*PatternLayoutComparison.*" -f 1 -wi 10 -i 10 -tu ns -bm sample
//
// Usage help:
// java -jar log4j-perf/target/benchmarks.jar -help
//
@State(Scope.Thread)
public class PatternLayoutComparisonBenchmark {

    final static String STR = "AB!(%087936DZYXQWEIOP$#^~-=/><nb"; // length=32
    final static LogEvent LOG4J2EVENT = createLog4j2Event();
    private static final Charset CHARSET_DEFAULT = Charset.defaultCharset();
    private static final String LOG4JPATTERN = "%d %5p [%t] %c{1} %X{transactionId} - %m%n";
    
    private final PatternLayout LOG4J2_PATTERN_LAYOUT = PatternLayout.newBuilder()
            .setPattern((String) LOG4JPATTERN)
            .setPatternSelector(null)
            .setConfiguration(null)
            .setRegexReplacement(null)
            .setCharset((Charset) CHARSET_DEFAULT)
            .setAlwaysWriteExceptions(false)
            .setNoConsoleNoAnsi(true)
            .setHeader(null)
            .setFooter(null)
            .build();

    private static LogEvent createLog4j2Event() {
        final Marker marker = null;
        final String fqcn = "com.mycom.myproject.mypackage.MyClass";
        final Level level = Level.DEBUG;
        final Message message = new SimpleMessage(STR);
        final Throwable t = null;
        final StringMap mdc = null;
        final ContextStack ndc = null;
        final String threadName = null;
        final StackTraceElement location = null;
        final long timestamp = 12345678;

        return Log4jLogEvent.newBuilder() //
                .setLoggerName("name(ignored)") //
                .setMarker(marker) //
                .setLoggerFqcn(fqcn) //
                .setLevel(level) //
                .setMessage(message) //
                .setThrown(t) //
                .setContextData(mdc) //
                .setContextStack(ndc) //
                .setThreadName(threadName) //
                .setSource(location) //
                .setTimeMillis(timestamp) //
                .build();
    }

    // Logback
    private static final String LOGBACKPATTERN = "%d %5p [%t] %c{0} %X{transactionId} - %m%n";
    private final PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder();
    private final LoggerContext context = new LoggerContext();
    private final Logger logger = context.getLogger(PatternLayoutComparisonBenchmark.class);
    private final ILoggingEvent LOGBACKEVENT = makeLoggingEvent(STR);
    private final ByteArrayOutputStream baos = new ByteArrayOutputStream();

    @Setup
    public void setUp() throws IOException {
        patternLayoutEncoder.setPattern(LOGBACKPATTERN);
        patternLayoutEncoder.setContext(context);
        patternLayoutEncoder.start();
        ((ch.qos.logback.classic.PatternLayout) patternLayoutEncoder.getLayout()).setOutputPatternAsHeader(false);
    }

    ILoggingEvent makeLoggingEvent(final String message) {
        return new LoggingEvent(PatternLayoutComparisonBenchmark.class.getName(), logger,
                ch.qos.logback.classic.Level.DEBUG, message, null, null);
    }

    @Benchmark
    public byte[] logback() throws IOException {
        baos.reset();
        return patternLayoutEncoder.encode(LOGBACKEVENT);
    }

    @Benchmark
    public byte[] log4j2() {
        return LOG4J2_PATTERN_LAYOUT.toByteArray(LOG4J2EVENT);
    }

}
