/*
 * 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.perf.util.StackDriver;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
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.State;
import org.openjdk.jmh.infra.Blackhole;

import java.lang.StackWalker;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Stream;

/**
 * Benchmark logging with logging disabled.
 * // ============================== HOW TO RUN THIS TEST: ====================================
 * //
 * // single thread:
 * // java -jar log4j-perf/target/benchmarks.jar ".*StackWalkBenchmark.*" -f 1 -wi 5 -i 10
 * //
 * // multiple threads (for example, 4 threads):
 * // java -jar log4j-perf/target/benchmarks.jar ".*StackWalkBenchmark.*" -f 1 -wi 5 -i 10 -t 4 -si true
 * //
 * // Usage help:
 * // java -jar log4j-perf/target/benchmarks.jar -help
 * //
 */
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class StackWalkBenchmark {

    private static final StackDriver stackDriver = new StackDriver();
    private final static ThreadLocal<String> FQCN = new ThreadLocal<>();
    private final static FqcnCallerLocator LOCATOR = new FqcnCallerLocator();
    private final static StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);

    @Param({"10", "20", "50"})
    private int initialDepth;

    @Param({"5", "10", "20"})
    private int callDepth;

    @Benchmark
    public void throwableSearch(Blackhole bh)  {

        stackDriver.deepCall(initialDepth, callDepth, (fqcn) -> {
            final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
            boolean found = false;
            for (int i = 0; i < stackTrace.length; i++) {
                final String className = stackTrace[i].getClassName();
                if (fqcn.equals(className)) {
                    found = true;
                    continue;
                }
                if (found  && !fqcn.equals(className)) {
                    return stackTrace[i];
                }
            }
            return null;
        });
    }

    @Benchmark
    public void stackWalkerWalk(Blackhole bh) {
        stackDriver.deepCall(initialDepth, callDepth, (fqcn) -> walker.walk(
                s -> s.dropWhile(f -> !f.getClassName().equals(fqcn)) // drop the top frames until we reach the logger
                        .dropWhile(f -> f.getClassName().equals(fqcn)) // drop the logger frames
                        .findFirst())
                .get()
                .toStackTraceElement());
    }

    @Benchmark
    public void baseline(Blackhole bh)  {

        stackDriver.deepCall(initialDepth, callDepth, (fqcn) -> null);
    }

    @Benchmark
    public void stackWalkerArray(Blackhole bh)  {

        stackDriver.deepCall(initialDepth, callDepth, (fqcn) -> {
            FQCN.set(fqcn);
            final StackWalker.StackFrame walk = walker.walk(LOCATOR);
            final StackTraceElement element = walk == null ? null : walk.toStackTraceElement();
            FQCN.set(null);
            return element;
        });
    }

    static final class FqcnCallerLocator implements Function<Stream<StackWalker.StackFrame>, StackWalker.StackFrame> {

        @Override
        public StackWalker.StackFrame apply(Stream<StackWalker.StackFrame> stackFrameStream) {
            String fqcn = FQCN.get();
            boolean foundFqcn = false;
            Object[] frames = stackFrameStream.toArray();
            for (int i = 0; i < frames.length ; ++i) {
                final String className = ((StackWalker.StackFrame) frames[i]).getClassName();
                if (!foundFqcn) {
                    // Skip frames until we find the FQCN
                    foundFqcn = className.equals(fqcn);
                } else if (!className.equals(fqcn)) {
                    // The frame is no longer equal to the FQCN so it is the one we want.
                    return (StackWalker.StackFrame) frames[i];
                } // Otherwise it is equal to the FQCN so we need to skip it.
            }
            // Should never happen
            return null;
        }
    }

}
