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

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;

/**
 * Utility for preventing primitive parameter values from being auto-boxed. Auto-boxing creates temporary objects
 * which contribute to pressure on the garbage collector. With this utility users can convert primitive values directly
 * into text without allocating temporary objects.
 * <p>
 * Example usage:
 * </p><pre>
 * import static org.apache.logging.log4j.util.Unbox.box;
 * ...
 * long longValue = 123456L;
 * double doubleValue = 3.14;
 * // prevent primitive values from being auto-boxed
 * logger.debug("Long value={}, double value={}", box(longValue), box(doubleValue));
 * </pre>
 * <p>
 * This class manages a small thread-local ring buffer of StringBuilders.
 * Each time one of the {@code box()} methods is called, the next slot in the ring buffer is used, until the ring
 * buffer is full and the first slot is reused. By default the Unbox ring buffer has 32 slots, so user code can
 * have up to 32 boxed primitives in a single logger call.
 * </p>
 * <p>
 * If more slots are required, set system property {@code log4j.unbox.ringbuffer.size} to the desired ring buffer size.
 * Note that the specified number will be rounded up to the nearest power of 2.
 * </p>
 * @since 2.6
 */
@PerformanceSensitive("allocation")
public class Unbox {
    private static final Logger LOGGER = StatusLogger.getLogger();
    private static final int BITS_PER_INT = 32;
    private static final int RINGBUFFER_MIN_SIZE = 32;
    private static final int RINGBUFFER_SIZE = calculateRingBufferSize("log4j.unbox.ringbuffer.size");
    private static final int MASK = RINGBUFFER_SIZE - 1;

    /**
     * State implementation that only puts JDK classes in ThreadLocals, so this is safe to be used from
     * web applications. Web application containers have thread pools that may hold on to ThreadLocal objects
     * after the application was stopped. This may prevent the classes of the application from being unloaded,
     * causing memory leaks.
     * <p>
     * Such memory leaks will not occur if only JDK classes are stored in ThreadLocals.
     * </p>
     */
    private static class WebSafeState {
        private final ThreadLocal<StringBuilder[]> ringBuffer = new ThreadLocal<>();
        private final ThreadLocal<int[]> current = new ThreadLocal<>();

        public StringBuilder getStringBuilder() {
            StringBuilder[] array = ringBuffer.get();
            if (array == null) {
                array = new StringBuilder[RINGBUFFER_SIZE];
                for (int i = 0; i < array.length; i++) {
                    array[i] = new StringBuilder(21);
                }
                ringBuffer.set(array);
                current.set(new int[1]);
            }
            final int[] index = current.get();
            final StringBuilder result = array[MASK & index[0]++];
            result.setLength(0);
            return result;
        }

        public boolean isBoxedPrimitive(final StringBuilder text) {
            final StringBuilder[] array = ringBuffer.get();
            if (array == null) {
                return false;
            }
            for (int i = 0; i < array.length; i++) {
                if (text == array[i]) {
                    return true;
                }
            }
            return false;
        }
    }

    private static class State {
        private final StringBuilder[] ringBuffer = new StringBuilder[RINGBUFFER_SIZE];
        private int current;
        State() {
            for (int i = 0; i < ringBuffer.length; i++) {
                ringBuffer[i] = new StringBuilder(21);
            }
        }

        public StringBuilder getStringBuilder() {
            final StringBuilder result = ringBuffer[MASK & current++];
            result.setLength(0);
            return result;
        }

        public boolean isBoxedPrimitive(final StringBuilder text) {
            for (int i = 0; i < ringBuffer.length; i++) {
                if (text == ringBuffer[i]) {
                    return true;
                }
            }
            return false;
        }
    }
    private static ThreadLocal<State> threadLocalState = new ThreadLocal<>();
    private static WebSafeState webSafeState = new WebSafeState();

    private Unbox() {
        // this is a utility
    }

    private static int calculateRingBufferSize(final String propertyName) {
        final String userPreferredRBSize = PropertiesUtil.getProperties().getStringProperty(propertyName,
                String.valueOf(RINGBUFFER_MIN_SIZE));
        try {
            int size = Integer.parseInt(userPreferredRBSize);
            if (size < RINGBUFFER_MIN_SIZE) {
                size = RINGBUFFER_MIN_SIZE;
                LOGGER.warn("Invalid {} {}, using minimum size {}.", propertyName, userPreferredRBSize,
                        RINGBUFFER_MIN_SIZE);
            }
            return ceilingNextPowerOfTwo(size);
        } catch (final Exception ex) {
            LOGGER.warn("Invalid {} {}, using default size {}.", propertyName, userPreferredRBSize,
                    RINGBUFFER_MIN_SIZE);
            return RINGBUFFER_MIN_SIZE;
        }
    }

    /**
     * Calculate the next power of 2, greater than or equal to x.
     * <p>
     * From Hacker's Delight, Chapter 3, Harry S. Warren Jr.
     *
     * @param x Value to round up
     * @return The next power of 2 from x inclusive
     */
    private static int ceilingNextPowerOfTwo(final int x) {
        return 1 << (BITS_PER_INT - Integer.numberOfLeadingZeros(x - 1));
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final float value) {
        return getSB().append(value);
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final double value) {
        return getSB().append(value);
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final short value) {
        return getSB().append(value);
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final int value) {
        return getSB().append(value);
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final char value) {
        return getSB().append(value);
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final long value) {
        return getSB().append(value);
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final byte value) {
        return getSB().append(value);
    }

    /**
     * Returns a {@code StringBuilder} containing the text representation of the specified primitive value.
     * This method will not allocate temporary objects.
     *
     * @param value the value whose text representation to return
     * @return a {@code StringBuilder} containing the text representation of the specified primitive value
     */
    @PerformanceSensitive("allocation")
    public static StringBuilder box(final boolean value) {
        return getSB().append(value);
    }

    private static State getState() {
        State state = threadLocalState.get();
        if (state == null) {
            state = new State();
            threadLocalState.set(state);
        }
        return state;
    }

    private static StringBuilder getSB() {
        return Constants.ENABLE_THREADLOCALS ? getState().getStringBuilder() : webSafeState.getStringBuilder();
    }

    /** For testing. */
    static int getRingbufferSize() {
        return RINGBUFFER_SIZE;
    }
}
