/*
 * Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//      Jaro Kuruc  - Initial API and implementation.
//      Tomas Kraus - EclipseLink 2.7 integration.
package org.eclipse.persistence.logging.slf4j;

import java.security.AccessController;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetSystemProperty;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.LogCategory;
import org.eclipse.persistence.logging.LogLevel;
import org.eclipse.persistence.logging.SessionLogEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * EclipseLink logger bridge over SLF4J.
 */
public class SLF4JLogger extends AbstractSessionLog {

    /** Logger callback interface. */
    private static interface LoggerCall {
        void log(final Logger logger, final String msg, final Throwable t);
        void log(final Logger logger, final String message);
    }

    /** {@code TRACE} level log. */
    private static final class LogTrace implements LoggerCall {
        @Override
        public void log(final Logger logger, final String msg, final Throwable t) {
            logger.trace(msg, t);
        }
        @Override
        public void log(final Logger logger, final String message) {
            logger.trace(message);
        }
    }

    /** {@code DEBUG} level log. */
    private static final class LogDebug implements LoggerCall {
        @Override
        public void log(final Logger logger, final String msg, final Throwable t) {
            logger.debug(msg, t);
        }
        @Override
        public void log(final Logger logger, final String message) {
            logger.debug(message);
        }
    }

    /** {@code INFO} level log. */
    private static final class LogInfo implements LoggerCall {
        @Override
        public void log(final Logger logger, final String msg, final Throwable t) {
            logger.info(msg, t);
        }
        @Override
        public void log(final Logger logger, final String message) {
            logger.info(message);
        }
    }

    /** {@code WARN} level log. */
    private static final class LogWarn implements LoggerCall {
        @Override
        public void log(final Logger logger, final String msg, final Throwable t) {
            logger.warn(msg, t);
        }
        @Override
        public void log(final Logger logger, final String message) {
            logger.warn(message);
        }
    }

    /** {@code ERROR} level log. */
    private static final class LogError implements LoggerCall {
        @Override
        public void log(final Logger logger, final String msg, final Throwable t) {
            logger.error(msg, t);
        }
        @Override
        public void log(final Logger logger, final String message) {
            logger.error(message);
        }
    }

    /** Do not log anything. */
    private static final class LogNop implements LoggerCall {
        @Override
        public void log(final Logger logger, final String msg, final Throwable t) {
        }
        @Override
        public void log(final Logger logger, final String message) {
        }
    }

    /** The default session name in case there is session name is missing. */
    public static final String ECLIPSELINK_NAMESPACE = "org.eclipse.persistence";

    /** SLF4J logger calls mapping for EclipseLink logging levels. */
    private static final LoggerCall[] loggerCall = new LoggerCall[LogLevel.length];

    /** Loggers lookup array. */
    private static final Logger[] categoryLoggers = new Logger[LogCategory.length];

    static {
        // Initialize loggers lookup array.
        for (int i = 0; i < LogCategory.length; i++) {
            categoryLoggers[i] = null;
        }
        // Initialize SLF4J logger calls mapping for EclipseLink logging levels.
        loggerCall[LogLevel.ALL.getId()]     = loggerCall[LogLevel.FINEST.getId()] = new LogTrace();
        loggerCall[LogLevel.FINER.getId()]   = loggerCall[LogLevel.FINE.getId()]   = new LogDebug();
        loggerCall[LogLevel.CONFIG.getId()]  = loggerCall[LogLevel.INFO.getId()]   = new LogInfo();
        loggerCall[LogLevel.WARNING.getId()] = new LogWarn();
        loggerCall[LogLevel.SEVERE.getId()]  = new LogError();
        loggerCall[LogLevel.OFF.getId()]     = new LogNop();
    }

    /**
     * Retrieve Logger for the given category.
     * @param category EclipseLink logging category
     * @return Logger for the given logging category.
     */
    private static Logger getLogger(final LogCategory category) {
        final Logger logger = categoryLoggers[category.getId()];
        if (logger != null) {
            return logger;
        }
        return categoryLoggers[category.getId()] = LoggerFactory.getLogger(category.getNameSpace());
    }

    /** Logging levels for individual logging categories. */
    private final LogLevel[] logLevels;

    /**
     * Creates an instance of EclipseLink logger bridge over SLF4J
     */
    public SLF4JLogger() {
        super();
        // Set default logging levels for all logging categories.
        final byte defaultLevel = LogLevel.toValue(level).getId();
        logLevels = new LogLevel[LogCategory.length];
        for (LogCategory category : LogCategory.values()) {
            final int i = category.getId();
            switch(category) {
            case ALL:
                logLevels[i] = LogLevel.toValue(defaultLevel);
                break;
            default:
                final String property = PersistenceUnitProperties.CATEGORY_LOGGING_LEVEL_ + category.getName();
                final String logLevelStr = PrivilegedAccessHelper.shouldUsePrivilegedAccess()
                        ? AccessController.doPrivileged(new PrivilegedGetSystemProperty(property))
                        : System.getProperty(property);
                logLevels[i] = LogLevel.toValue(
                        logLevelStr != null ? translateStringToLoggingLevel(logLevelStr) : defaultLevel);
            }
        }
    }

    /**
     * Get the logging level for the default logging category.
     * @return level Current logging level for default the default logging category.
     */
    @Override
    public int getLevel() {
        return logLevels[LogCategory.ALL.getId()].getId();
    }

    /**
     * Get the logging level for the specified logging category.
     * @param categoryName The {@link String} representation of an EclipseLink logging category.
     * @return level Current logging level for default the default logging category.
     */
    @Override
    public int getLevel(final String categoryName) {
        final LogCategory category = LogCategory.toValue(categoryName);
        if (category == null) {
            throw new IllegalArgumentException("Unknown logging category name.");
        }
        return logLevels[category.getId()].getId();
    }

    /**
     * Set the logging level for the default logging category.
     * @param level The logging level to be set.
     */
    @Override
    public void setLevel(final int level) {
        super.setLevel(level);
        logLevels[LogCategory.ALL.getId()] = LogLevel.toValue(level);
        // TODO: Handle logging levels on SLF4J side too.
    }

    /**
     * Set the logging level for the specified logging category.
     * @param level        The logging level to be set.
     * @param categoryName The {@link String} representation of an EclipseLink logging category.
     */
    @Override
    public void setLevel(final int level, final String categoryName) {
        final LogCategory category = LogCategory.toValue(categoryName);
        if (category == null) {
            throw new IllegalArgumentException("Unknown logging category name.");
        }
        logLevels[category.getId()] = LogLevel.toValue(level);
        // TODO: Handle logging levels on SLF4J side too.
    }

    /**
     * Check if a message of the given level would actually be logged under logging level for the default logging
     * category.
     * @param level Message logging level.
     * @return Value of {@code true} if the given message logging level will be logged or {@code false} otherwise.
     */
    @Override
    public boolean shouldLog(final int level) {
        return logLevels[LogCategory.ALL.getId()].shouldLog((byte)level);
    }

    /**
     * Check if a message of the given level would actually be logged under logging level for the specified logging
     * category.
     * @param level Message logging level.
     * @param categoryName The {@link String} representation of an EclipseLink logging category.
     * @return Value of {@code true} if the given message logging level will be logged or {@code false} otherwise.
     */
    @Override
    public boolean shouldLog(final int level, final String categoryName) {
        final LogCategory category = LogCategory.toValue(categoryName);
        if (category == null) {
            throw new IllegalArgumentException("Unknown logging category name.");
        }
        return logLevels[category.getId()].shouldLog((byte)level);
    }

    @Override
    public void log(final SessionLogEntry logEntry) {
        if (logEntry == null) {
            return;
        }
        final LogCategory category = LogCategory.toValue(logEntry.getNameSpace());
        if (category == null) {
            throw new IllegalArgumentException("Unknown logging category name.");
        }
        final byte levelId = (byte)logEntry.getLevel();
        if (logLevels[category.getId()].shouldLog(levelId)) {
            final LogLevel level = LogLevel.toValue(levelId);
            final Logger logger = getLogger(category);
            if (logEntry.hasException()) {
                if (shouldLogExceptionStackTrace()) {
                    // Message is rendered on EclipseLink side. SLF4J gets final String. Exception is passed too.
                    loggerCall[level.getId()].log(logger, formatMessage(logEntry), logEntry.getException());
                } else {
                    // Exception message is rendered on EclipseLink side. SLF4J gets final String.
                    loggerCall[level.getId()].log(logger, logEntry.getException().toString());
                }
            } else {
                // Message is rendered on EclipseLink side. SLF4J gets final String.
                loggerCall[level.getId()].log(logger, formatMessage(logEntry));
            }
        }
    }

}
