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

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.logging.log4j.Level;

/**
 * Default implementation of LevelConverter strategy.
 * <p>
 * Since 2.4, supports custom JUL levels by mapping them to their closest mapped neighbour.
 * </p>
 *
 * @since 2.1
 */
public class DefaultLevelConverter implements LevelConverter {

    static final class JulLevelComparator implements Comparator<java.util.logging.Level>, Serializable {
        private static final long serialVersionUID = 1L;
        @Override
        public int compare(final java.util.logging.Level level1, final java.util.logging.Level level2) {
            return Integer.compare(level1.intValue(), level2.intValue());
        }
    }

    private final ConcurrentMap<java.util.logging.Level, Level> julToLog4j = new ConcurrentHashMap<>(9);
    private final Map<Level, java.util.logging.Level> log4jToJul = new IdentityHashMap<>(10);
    private final List<java.util.logging.Level> sortedJulLevels = new ArrayList<>(9);

    public DefaultLevelConverter() {
        // Map JUL to Log4j
        mapJulToLog4j(java.util.logging.Level.ALL, Level.ALL);
        mapJulToLog4j(java.util.logging.Level.FINEST, LevelTranslator.FINEST);
        mapJulToLog4j(java.util.logging.Level.FINER, Level.TRACE);
        mapJulToLog4j(java.util.logging.Level.FINE, Level.DEBUG);
        mapJulToLog4j(java.util.logging.Level.CONFIG, LevelTranslator.CONFIG);
        mapJulToLog4j(java.util.logging.Level.INFO, Level.INFO);
        mapJulToLog4j(java.util.logging.Level.WARNING, Level.WARN);
        mapJulToLog4j(java.util.logging.Level.SEVERE, Level.ERROR);
        mapJulToLog4j(java.util.logging.Level.OFF, Level.OFF);
        // Map Log4j to JUL
        mapLog4jToJul(Level.ALL, java.util.logging.Level.ALL);
        mapLog4jToJul(LevelTranslator.FINEST, java.util.logging.Level.FINEST);
        mapLog4jToJul(Level.TRACE, java.util.logging.Level.FINER);
        mapLog4jToJul(Level.DEBUG, java.util.logging.Level.FINE);
        mapLog4jToJul(LevelTranslator.CONFIG, java.util.logging.Level.CONFIG);
        mapLog4jToJul(Level.INFO, java.util.logging.Level.INFO);
        mapLog4jToJul(Level.WARN, java.util.logging.Level.WARNING);
        mapLog4jToJul(Level.ERROR, java.util.logging.Level.SEVERE);
        mapLog4jToJul(Level.FATAL, java.util.logging.Level.SEVERE);
        mapLog4jToJul(Level.OFF, java.util.logging.Level.OFF);
        // Sorted Java levels
        sortedJulLevels.addAll(julToLog4j.keySet());
        Collections.sort(sortedJulLevels, new JulLevelComparator());

    }

    private long distance(final java.util.logging.Level javaLevel, final java.util.logging.Level customJavaLevel) {
        return Math.abs((long) customJavaLevel.intValue() - (long) javaLevel.intValue());
    }

    /*
     * TODO consider making public for advanced configuration.
     */
    private void mapJulToLog4j(final java.util.logging.Level julLevel, final Level level) {
        julToLog4j.put(julLevel, level);
    }

    /*
     * TODO consider making public for advanced configuration.
     */
    private void mapLog4jToJul(final Level level, final java.util.logging.Level julLevel) {
        log4jToJul.put(level, julLevel);
    }

    private Level nearestLevel(final java.util.logging.Level customJavaLevel) {
        long prevDist = Long.MAX_VALUE;
        java.util.logging.Level prevLevel = null;
        for (final java.util.logging.Level mappedJavaLevel : sortedJulLevels) {
            final long distance = distance(customJavaLevel, mappedJavaLevel);
            if (distance > prevDist) {
                return julToLog4j.get(prevLevel);
            }
            prevDist = distance;
            prevLevel = mappedJavaLevel;
        }
        return julToLog4j.get(prevLevel);
    }

    @Override
    public java.util.logging.Level toJavaLevel(final Level level) {
        return log4jToJul.get(level);
    }

    @Override
    public Level toLevel(final java.util.logging.Level javaLevel) {
        if (javaLevel == null) {
            return null;
        }
        final Level level = julToLog4j.get(javaLevel);
        if (level != null) {
            return level;
        }
        final Level nearestLevel = nearestLevel(javaLevel);
        julToLog4j.put(javaLevel, nearestLevel);
        return nearestLevel;
    }
}
