/*
 * 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 org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
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.Assert;

import java.util.Random;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 *
 */
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 = 200;
    private static int[] values = new int[RAND_SIZE];

    @BeforeClass
    public static void setupClass() {

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

        for (int i=0; i < WARMUP; ++i) {
            overhead();
        }
        System.gc();
        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();
        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 debugLogger() {
        System.gc();
        Timer timer = new Timer("DebugLogger", LOOP_CNT);
        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() {
        int values[] = new int[RAND_SIZE];
        Random rand = new SimpleRandom();

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

    private static class SimpleRandom extends Random {
        private int low = 5;
        private int high = 55;

        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(int array[]) {
        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]) {
                    int temp = array[j-1];
                    array[j-1] = array[j];
                    array[j] = temp;
                }
            }
        }
    }
}
