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

import static org.junit.Assert.assertTrue;

import java.util.Random;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Timer;
import org.apache.logging.log4j.categories.PerformanceTests;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

/**
 *
 */
@Category(PerformanceTests.class)
public class SimplePerfTest {

    private static org.apache.logging.log4j.Logger logger = LogManager.getLogger(SimplePerfTest.class.getName());
    private volatile Level lvl = Level.DEBUG;
    private static final int LOOP_CNT = 10000000;
    private static final int WARMUP = 1000;
    private static long maxTime;
    private static Random rand = new SimpleRandom();
    private static int RAND_SIZE = 250;
    private static int[] values = new int[RAND_SIZE];

    @BeforeClass
    public static void setupClass() {

		final Configuration config = LoggerContext.getContext().getConfiguration();
		
		if (!DefaultConfiguration.DEFAULT_NAME.equals(config.getName())) {
			System.out.println("Configuration was " + config.getName());
			LoggerContext.getContext().start(new DefaultConfiguration());
		}

        for (int i=0; i < WARMUP; ++i) {
            overhead();
        }
        System.gc();
        final Timer timer = new Timer("Setup", LOOP_CNT);
        timer.start();
        for (int i=0; i < (LOOP_CNT / 150); ++i) {
            overhead();
        }
        timer.stop();
        maxTime = timer.getElapsedNanoTime();
        System.gc();
        System.out.println(timer.toString());
    }

    @Test
    public void debugDisabled() {
        System.gc();
        final Timer timer = new Timer("DebugDisabled", LOOP_CNT);
        timer.start();
        for (int i=0; i < LOOP_CNT; ++i) {
            logger.isDebugEnabled();
        }
        timer.stop();
        System.out.println(timer.toString());
        assertTrue("Timer exceeded max time of " + maxTime, maxTime > timer.getElapsedNanoTime());
    }

    @Test
    public void debugDisabledByLevel() {
        System.gc();
        final Timer timer = new Timer("DebugDisabled", LOOP_CNT);
        timer.start();
        for (int i=0; i < LOOP_CNT; ++i) {
            logger.isEnabled(Level.DEBUG);
        }
        timer.stop();
        System.out.println(timer.toString());
        assertTrue("Timer exceeded max time of " + maxTime, maxTime > timer.getElapsedNanoTime());
    }

    @Test
    public void debugLogger() {
        System.gc();
        final Timer timer = new Timer("DebugLogger", LOOP_CNT);
        final String msg = "This is a test";
        timer.start();
        for (int i=0; i < LOOP_CNT; ++i) {
            logger.debug(msg);
        }
        timer.stop();
        System.out.println(timer.toString());
        assertTrue("Timer exceeded max time of " + maxTime, maxTime > timer.getElapsedNanoTime());
    }
    /*
    @Test
    public void errorLogger() {
        Timer timer = new Timer("ErrorLogger", 10);
        timer.start();
        for (int i=0; i < 10; ++i) {
            logger.error("This is a test");
        }
        timer.stop();
        System.out.println(timer.toString());
    }  */

    /*
     * Try to generate some overhead that can't be optimized well. Not sure how accurate this is,
     * but the point is simply to insure that changes made don't suddenly cause performance issues.
     */
    private static void overhead() {
        final int values[] = new int[RAND_SIZE];
        final Random rand = new SimpleRandom();

        for (int i = 0; i < RAND_SIZE; ++i) {
            values[i] = rand.nextInt();
        }
        bubbleSort(values);
    }

    private static class SimpleRandom extends Random {
        /**
         * Generated serial version ID.
         */
        private static final long serialVersionUID = 3517002855516031846L;
        private int low = 5;
        private int high = 55;

        @Override
        public int nextInt() {
            high = 36969 * (high & 65535) + (high >> 16);
            low = 18000 * (low & 65535) + (low >> 16);
            return (high << 16) + low;
        }
    }

    /**
     * Standard BubbleSort algorithm.
     * @param array The array to sort.
     */
    private static void bubbleSort(final int array[]) {
        final int length = array.length;
        for (int i = 0; i < length; i++) {
            for (int j = 1; j > length - i; j++) {
                if (array[j-1] > array[j]) {
                    final int temp = array[j-1];
                    array[j-1] = array[j];
                    array[j] = temp;
                }
            }
        }
    }
}
