package org.apache.commons.jcs.log;

import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;

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

/**
 * This is a wrapper around the <code>java.util.logging.Logger</code> implementing our own
 * <code>Log</code> interface.
 * <p>
 * This is the mapping of the log levels
 * </p>
 * <pre>
 * Java Level   Log Level
 * SEVERE       FATAL
 * SEVERE       ERROR
 * WARNING      WARN
 * INFO         INFO
 * FINE         DEBUG
 * FINER        TRACE
 * </pre>
 */
public class JulLogAdapter implements Log
{
    private Logger logger;

    /**
     * Construct a JUL Logger wrapper
     *
     * @param logger the JUL Logger
     */
    public JulLogAdapter(Logger logger)
    {
        super();
        this.logger = logger;
    }

    private void log(Level level, String message)
    {
        if (logger.isLoggable(level))
        {
            logger.logp(level, logger.getName(), "", message);
        }
    }

    private void log(Level level, Object message)
    {
        if (logger.isLoggable(level))
        {
            if (message instanceof Throwable)
            {
                logger.logp(level, logger.getName(), "", "Exception:", (Throwable) message);
            }
            else
            {
                logger.logp(level, logger.getName(), "",
                        message == null ? null : message.toString());
            }
        }
    }

    private void log(Level level, String message, Throwable t)
    {
        if (logger.isLoggable(level))
        {
            logger.logp(level, logger.getName(), "", message, t);
        }
    }

    private void log(Level level, String message, Object... params)
    {
        if (logger.isLoggable(level))
        {
            MessageFormatter formatter = new MessageFormatter(message, params);
            if (formatter.hasThrowable())
            {
                logger.logp(level, logger.getName(), "",
                        formatter.getFormattedMessage(), formatter.getThrowable());
            }
            else
            {
                logger.logp(level, logger.getName(), "",
                        formatter.getFormattedMessage());
            }
        }
    }

    private void log(Level level, String message, Supplier<?>... paramSuppliers)
    {
        if (logger.isLoggable(level))
        {
            MessageFormatter formatter = new MessageFormatter(message, paramSuppliers);
            if (formatter.hasThrowable())
            {
                logger.logp(level, logger.getName(), "",
                        formatter.getFormattedMessage(), formatter.getThrowable());
            }
            else
            {
                logger.logp(level, logger.getName(), "",
                        formatter.getFormattedMessage());
            }
        }
    }

    /**
     * Logs a message object with the DEBUG level.
     *
     * @param message the message string to log.
     */
    @Override
    public void debug(String message)
    {
        log(Level.FINE, message);
    }

    /**
     * Logs a message object with the DEBUG level.
     *
     * @param message the message object to log.
     */
    @Override
    public void debug(Object message)
    {
        log(Level.FINE, message);
    }

    /**
     * Logs a message with parameters at the DEBUG level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param params parameters to the message.
     * @see #getMessageFactory()
     */
    @Override
    public void debug(String message, Object... params)
    {
        log(Level.FINE, message, params);
    }

    /**
     * Logs a message with parameters which are only to be constructed if the
     * logging level is the DEBUG level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param paramSuppliers An array of functions, which when called,
     *        produce the desired log message parameters.
     */
    @Override
    public void debug(String message, Supplier<?>... paramSuppliers)
    {
        log(Level.FINE, message, paramSuppliers);
    }

    /**
     * Logs a message at the DEBUG level including the stack trace of the {@link Throwable}
     * <code>t</code> passed as parameter.
     *
     * @param message the message to log.
     * @param t the exception to log, including its stack trace.
     */
    @Override
    public void debug(String message, Throwable t)
    {
        log(Level.FINE, message, t);
    }

    /**
     * Logs a message object with the ERROR level.
     *
     * @param message the message string to log.
     */
    @Override
    public void error(String message)
    {
        log(Level.SEVERE, message);
    }

    /**
     * Logs a message object with the ERROR level.
     *
     * @param message the message object to log.
     */
    @Override
    public void error(Object message)
    {
        log(Level.SEVERE, message);
    }

    /**
     * Logs a message with parameters at the ERROR level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param params parameters to the message.
     */
    @Override
    public void error(String message, Object... params)
    {
        log(Level.SEVERE, message, params);
    }

    /**
     * Logs a message with parameters which are only to be constructed if the
     * logging level is the ERROR level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param paramSuppliers An array of functions, which when called, produce
     *        the desired log message parameters.
     * @since 2.4
     */
    @Override
    public void error(String message, Supplier<?>... paramSuppliers)
    {
        log(Level.SEVERE, message, paramSuppliers);
    }

    /**
     * Logs a message at the ERROR level including the stack trace of the {@link Throwable}
     * <code>t</code> passed as parameter.
     *
     * @param message the message object to log.
     * @param t the exception to log, including its stack trace.
     */
    @Override
    public void error(String message, Throwable t)
    {
        log(Level.SEVERE, message, t);
    }

    /**
     * Logs a message object with the FATAL level.
     *
     * @param message the message string to log.
     */
    @Override
    public void fatal(String message)
    {
        log(Level.SEVERE, message);
    }

    /**
     * Logs a message object with the FATAL level.
     *
     * @param message the message object to log.
     */
    @Override
    public void fatal(Object message)
    {
        log(Level.SEVERE, message);
    }

    /**
     * Logs a message with parameters at the FATAL level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param params parameters to the message.
     */
    @Override
    public void fatal(String message, Object... params)
    {
        log(Level.SEVERE, message, params);
    }

    /**
     * Logs a message with parameters which are only to be constructed if the
     * logging level is the FATAL level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param paramSuppliers An array of functions, which when called, produce the
     *        desired log message parameters.
     */
    @Override
    public void fatal(String message, Supplier<?>... paramSuppliers)
    {
        log(Level.SEVERE, message, paramSuppliers);
    }

    /**
     * Logs a message at the FATAL level including the stack trace of the {@link Throwable}
     * <code>t</code> passed as parameter.
     *
     * @param message the message object to log.
     * @param t the exception to log, including its stack trace.
     */
    @Override
    public void fatal(String message, Throwable t)
    {
        log(Level.SEVERE, message, t);
    }

    /**
     * Gets the logger name.
     *
     * @return the logger name.
     */
    @Override
    public String getName()
    {
        return logger.getName();
    }

    /**
     * Logs a message object with the INFO level.
     *
     * @param message the message string to log.
     */
    @Override
    public void info(String message)
    {
        log(Level.INFO, message);
    }

    /**
     * Logs a message object with the INFO level.
     *
     * @param message the message object to log.
     */
    @Override
    public void info(Object message)
    {
        log(Level.INFO, message);
    }

    /**
     * Logs a message with parameters at the INFO level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param params parameters to the message.
     */
    @Override
    public void info(String message, Object... params)
    {
        log(Level.INFO, message, params);
    }

    /**
     * Logs a message with parameters which are only to be constructed if the
     * logging level is the INFO level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param paramSuppliers An array of functions, which when called, produce
     *        the desired log message parameters.
     */
    @Override
    public void info(String message, Supplier<?>... paramSuppliers)
    {
        log(Level.INFO, message, paramSuppliers);
    }

    /**
     * Logs a message at the INFO level including the stack trace of the {@link Throwable}
     * <code>t</code> passed as parameter.
     *
     * @param message the message object to log.
     * @param t the exception to log, including its stack trace.
     */
    @Override
    public void info(String message, Throwable t)
    {
        log(Level.INFO, message, t);
    }

    /**
     * Checks whether this Logger is enabled for the DEBUG Level.
     *
     * @return boolean - {@code true} if this Logger is enabled for level DEBUG, {@code false}
     *         otherwise.
     */
    @Override
    public boolean isDebugEnabled()
    {
        return logger.isLoggable(Level.FINE);
    }

    /**
     * Checks whether this Logger is enabled for the ERROR Level.
     *
     * @return boolean - {@code true} if this Logger is enabled for level ERROR, {@code false}
     *         otherwise.
     */
    @Override
    public boolean isErrorEnabled()
    {
        return logger.isLoggable(Level.SEVERE);
    }

    /**
     * Checks whether this Logger is enabled for the FATAL Level.
     *
     * @return boolean - {@code true} if this Logger is enabled for level FATAL, {@code false}
     *         otherwise.
     */
    @Override
    public boolean isFatalEnabled()
    {
        return logger.isLoggable(Level.SEVERE);
    }

    /**
     * Checks whether this Logger is enabled for the INFO Level.
     *
     * @return boolean - {@code true} if this Logger is enabled for level INFO, {@code false}
     *         otherwise.
     */
    @Override
    public boolean isInfoEnabled()
    {
        return logger.isLoggable(Level.INFO);
    }

    /**
     * Checks whether this Logger is enabled for the TRACE level.
     *
     * @return boolean - {@code true} if this Logger is enabled for level TRACE, {@code false}
     *         otherwise.
     */
    @Override
    public boolean isTraceEnabled()
    {
        return logger.isLoggable(Level.FINER);
    }

    /**
     * Checks whether this Logger is enabled for the WARN Level.
     *
     * @return boolean - {@code true} if this Logger is enabled for level WARN, {@code false}
     *         otherwise.
     */
    @Override
    public boolean isWarnEnabled()
    {
        return logger.isLoggable(Level.WARNING);
    }

    /**
     * Logs a message object with the TRACE level.
     *
     * @param message the message string to log.
     */
    @Override
    public void trace(String message)
    {
        log(Level.FINER, message);
    }

    /**
     * Logs a message object with the TRACE level.
     *
     * @param message the message object to log.
     */
    @Override
    public void trace(Object message)
    {
        log(Level.FINER, message);
    }

    /**
     * Logs a message with parameters at the TRACE level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param params parameters to the message.
     */
    @Override
    public void trace(String message, Object... params)
    {
        log(Level.FINER, message, params);
    }

    /**
     * Logs a message with parameters which are only to be constructed if the
     * logging level is the TRACE level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param paramSuppliers An array of functions, which when called, produce
     *        the desired log message parameters.
     */
    @Override
    public void trace(String message, Supplier<?>... paramSuppliers)
    {
        log(Level.FINER, message, paramSuppliers);
    }

    /**
     * Logs a message at the TRACE level including the stack trace of the {@link Throwable}
     * <code>t</code> passed as parameter.
     *
     * @param message the message object to log.
     * @param t the exception to log, including its stack trace.
     * @see #debug(String)
     */
    @Override
    public void trace(String message, Throwable t)
    {
        log(Level.FINER, message, t);
    }

    /**
     * Logs a message object with the WARN level.
     *
     * @param message the message string to log.
     */
    @Override
    public void warn(String message)
    {
        log(Level.WARNING, message);
    }

    /**
     * Logs a message object with the WARN level.
     *
     * @param message the message object to log.
     */
    @Override
    public void warn(Object message)
    {
        log(Level.WARNING, message);
    }

    /**
     * Logs a message with parameters at the WARN level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param params parameters to the message.
     */
    @Override
    public void warn(String message, Object... params)
    {
        log(Level.WARNING, message, params);
    }

    /**
     * Logs a message with parameters which are only to be constructed if the
     * logging level is the WARN level.
     *
     * @param message the message to log; the format depends on the message factory.
     * @param paramSuppliers An array of functions, which when called, produce
     *        the desired log message parameters.
     */
    @Override
    public void warn(String message, Supplier<?>... paramSuppliers)
    {
        log(Level.WARNING, message, paramSuppliers);
    }

    /**
     * Logs a message at the WARN level including the stack trace of the {@link Throwable}
     * <code>t</code> passed as parameter.
     *
     * @param message the message object to log.
     * @param t the exception to log, including its stack trace.
     */
    @Override
    public void warn(String message, Throwable t)
    {
        log(Level.WARNING, message, t);
    }
}