/*
 * 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.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
import org.apache.logging.log4j.core.time.internal.format.FastDateFormat;
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.Scope;
import org.openjdk.jmh.annotations.State;

/**
 * Tests performance of various time format implementation.
 */
// ============================== HOW TO RUN THIS TEST: ====================================
//
// single thread:
// java -jar log4j-perf/target/benchmarks.jar ".*TimeFormat.*" -f 1 -wi 5 -i 10
//
// multiple threads (for example, 4 threads):
// java -jar log4j-perf/target/benchmarks.jar ".*TimeFormat.*" -f 1 -wi 5 -i 5 -t 4 -si true
//
// Usage help:
// java -jar log4j-perf/target/benchmarks.jar -help
//
@State(Scope.Benchmark)
public class TimeFormatBenchmark {

    ThreadLocal<SimpleDateFormat> threadLocalSimpleDateFormat = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("HH:mm:ss.SSS");
        }
    };
    FastDateFormat fastDateFormat = FastDateFormat.getInstance("HH:mm:ss.SSS");
    FixedDateFormat fixedDateFormat = FixedDateFormat.createIfSupported(new String[]{"ABSOLUTE"});
    volatile long midnightToday = 0;
    volatile long midnightTomorrow = 0;

    @State(Scope.Thread)
    public static class BufferState {
        final ByteBuffer buffer = ByteBuffer.allocate(12);
        final StringBuilder stringBuilder = new StringBuilder(12);
        final char[] charArray = new char[12];
    }

    private long millisSinceMidnight(final long now) {
        if (now >= midnightTomorrow) {
            midnightToday = calcMidnightMillis(now, 0);
            midnightTomorrow = calcMidnightMillis(now, 1);
        }
        return now - midnightToday;
    }

    private long calcMidnightMillis(final long time, final int addDays) {
        final Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(time);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DATE, addDays);
        return cal.getTimeInMillis();
    }

    public static void main(final String[] args) {
        System.out.println(new TimeFormatBenchmark().fixedBitFiddlingReuseCharArray(new BufferState()));
        System.out.println(new TimeFormatBenchmark().fixedFormatReuseStringBuilder(new BufferState()));
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public String simpleDateFormat() {
        return threadLocalSimpleDateFormat.get().format(new Date());
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public String fastDateFormatCreateNewStringBuilder() {
        return fastDateFormat.format(new Date());
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public String fastDateFormatReuseStringBuilder(final BufferState state) {
        state.stringBuilder.setLength(0);
        fastDateFormat.format(new Date(), state.stringBuilder);
        return new String(state.stringBuilder);
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public String fixedBitFiddlingReuseCharArray(final BufferState state) {
        final int len = formatCharArrayBitFiddling(System.currentTimeMillis(), state.charArray, 0);
        return new String(state.charArray, 0, len);
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public String fixedDateFormatCreateNewCharArray(final BufferState state) {
        return fixedDateFormat.format(System.currentTimeMillis());
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public String fixedDateFormatReuseCharArray(final BufferState state) {
        final int len = fixedDateFormat.format(System.currentTimeMillis(), state.charArray, 0);
        return new String(state.charArray, 0, len);
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public String fixedFormatReuseStringBuilder(final BufferState state) {
        state.stringBuilder.setLength(0);
        formatStringBuilder(System.currentTimeMillis(), state.stringBuilder);
        return new String(state.stringBuilder);
    }

    int formatCharArrayBitFiddling(final long time, final char[] buffer, int pos) {
        // Calculate values by getting the ms values first and do then
        // shave off the hour minute and second values with multiplications
        // and bit shifts instead of simple but expensive divisions.

        // Get daytime in ms which does fit into an int
        // int ms = (int) (time % 86400000);
        int ms = (int) (millisSinceMidnight(time));

        // well ... it works
        final int hour = (int) (((ms >> 7) * 9773437L) >> 38);
        ms -= 3600000 * hour;

        final int minute = (int) (((ms >> 5) * 2290650L) >> 32);
        ms -= 60000 * minute;

        final int second = ((ms >> 3) * 67109) >> 23;
        ms -= 1000 * second;

        // Hour
        // 13/128 is nearly the same as /10 for values up to 65
        int temp = (hour * 13) >> 7;
        buffer[pos++] = ((char) (temp + '0'));

        // Do subtract to get remainder instead of doing % 10
        buffer[pos++] = ((char) (hour - 10 * temp + '0'));
        buffer[pos++] = ((char) ':');

        // Minute
        // 13/128 is nearly the same as /10 for values up to 65
        temp = (minute * 13) >> 7;
        buffer[pos++] = ((char) (temp + '0'));

        // Do subtract to get remainder instead of doing % 10
        buffer[pos++] = ((char) (minute - 10 * temp + '0'));
        buffer[pos++] = ((char) ':');

        // Second
        // 13/128 is nearly the same as /10 for values up to 65
        temp = (second * 13) >> 7;
        buffer[pos++] = ((char) (temp + '0'));
        buffer[pos++] = ((char) (second - 10 * temp + '0'));
        buffer[pos++] = ((char) '.');

        // Millisecond
        // 41/4096 is nearly the same as /100
        temp = (ms * 41) >> 12;
        buffer[pos++] = ((char) (temp + '0'));

        ms -= 100 * temp;
        temp = (ms * 205) >> 11; // 205/2048 is nearly the same as /10
        buffer[pos++] = ((char) (temp + '0'));

        ms -= 10 * temp;
        buffer[pos++] = ((char) (ms + '0'));
        return pos;
    }

    StringBuilder formatStringBuilder(final long time, final StringBuilder buffer) {
        // Calculate values by getting the ms values first and do then
        // calculate the hour minute and second values divisions.

        // Get daytime in ms which does fit into an int
        // int ms = (int) (time % 86400000);
        int ms = (int) (millisSinceMidnight(time));

        final int hours = ms / 3600000;
        ms -= 3600000 * hours;

        final int minutes = ms / 60000;
        ms -= 60000 * minutes;

        final int seconds = ms / 1000;
        ms -= 1000 * seconds;

        // Hour
        int temp = hours / 10;
        buffer.append((char) (temp + '0'));

        // Do subtract to get remainder instead of doing % 10
        buffer.append((char) (hours - 10 * temp + '0'));
        buffer.append((char) ':');

        // Minute
        temp = minutes / 10;
        buffer.append((char) (temp + '0'));

        // Do subtract to get remainder instead of doing % 10
        buffer.append((char) (minutes - 10 * temp + '0'));
        buffer.append((char) ':');

        // Second
        temp = seconds / 10;
        buffer.append((char) (temp + '0'));
        buffer.append((char) (seconds - 10 * temp + '0'));
        buffer.append((char) '.');

        // Millisecond
        temp = ms / 100;
        buffer.append((char) (temp + '0'));

        ms -= 100 * temp;
        temp = ms / 10;
        buffer.append((char) (temp + '0'));

        ms -= 10 * temp;
        buffer.append((char) (ms + '0'));
        return buffer;
    }

    int formatCharArray(final long time, final char[] buffer, int pos) {
        // Calculate values by getting the ms values first and do then
        // calculate the hour minute and second values divisions.

        // Get daytime in ms which does fit into an int
        // int ms = (int) (time % 86400000);
        int ms = (int) (millisSinceMidnight(time));

        final int hours = ms / 3600000;
        ms -= 3600000 * hours;

        final int minutes = ms / 60000;
        ms -= 60000 * minutes;

        final int seconds = ms / 1000;
        ms -= 1000 * seconds;

        // Hour
        int temp = hours / 10;
        buffer[pos++] = ((char) (temp + '0'));

        // Do subtract to get remainder instead of doing % 10
        buffer[pos++] = ((char) (hours - 10 * temp + '0'));
        buffer[pos++] = ((char) ':');

        // Minute
        temp = minutes / 10;
        buffer[pos++] = ((char) (temp + '0'));

        // Do subtract to get remainder instead of doing % 10
        buffer[pos++] = ((char) (minutes - 10 * temp + '0'));
        buffer[pos++] = ((char) ':');

        // Second
        temp = seconds / 10;
        buffer[pos++] = ((char) (temp + '0'));
        buffer[pos++] = ((char) (seconds - 10 * temp + '0'));
        buffer[pos++] = ((char) '.');

        // Millisecond
        temp = ms / 100;
        buffer[pos++] = ((char) (temp + '0'));

        ms -= 100 * temp;
        temp = ms / 10;
        buffer[pos++] = ((char) (temp + '0'));

        ms -= 10 * temp;
        buffer[pos++] = ((char) (ms + '0'));
        return pos;
    }
}
