//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.util.log;

import java.util.Properties;

/* ------------------------------------------------------------ */
/** Abstract Logger.
 * Manages the atomic registration of the logger by name.
 */
public abstract class AbstractLogger implements Logger
{
    public static final int LEVEL_DEFAULT = -1;
    public static final int LEVEL_ALL = 0;
    public static final int LEVEL_DEBUG = 1;
    public static final int LEVEL_INFO = 2;
    public static final int LEVEL_WARN = 3;
    public static final int LEVEL_OFF = 10;
        
    @Override
    public final Logger getLogger(String name)
    {
        if (isBlank(name))
            return this;

        final String basename = getName();
        final String fullname = (isBlank(basename) || Log.getRootLogger()==this)?name:(basename + "." + name);
        
        Logger logger = Log.getLoggers().get(fullname);
        if (logger == null)
        {
            Logger newlog = newLogger(fullname);
            
            logger = Log.getMutableLoggers().putIfAbsent(fullname,newlog);
            if (logger == null)
                logger=newlog;
        }

        return logger;
    }
    

    protected abstract Logger newLogger(String fullname);

    /**
     * A more robust form of name blank test. Will return true for null names, and names that have only whitespace
     *
     * @param name
     *            the name to test
     * @return true for null or blank name, false if any non-whitespace character is found.
     */
    private static boolean isBlank(String name)
    {
        if (name == null)
        {
            return true;
        }
        int size = name.length();
        char c;
        for (int i = 0; i < size; i++)
        {
            c = name.charAt(i);
            if (!Character.isWhitespace(c))
            {
                return false;
            }
        }
        return true;
    }
    
    /**
     * Get the Logging Level for the provided log name. Using the FQCN first, then each package segment from longest to
     * shortest.
     *
     * @param props
     *            the properties to check
     * @param name
     *            the name to get log for
     * @return the logging level
     */
    public static int lookupLoggingLevel(Properties props, final String name)
    {
        if ((props == null) || (props.isEmpty()) || name==null )
            return LEVEL_DEFAULT;
        
        // Calculate the level this named logger should operate under.
        // Checking with FQCN first, then each package segment from longest to shortest.
        String nameSegment = name;
    
        while ((nameSegment != null) && (nameSegment.length() > 0))
        {
            String levelStr = props.getProperty(nameSegment + ".LEVEL");
            // System.err.printf("[StdErrLog.CONFIG] Checking for property [%s.LEVEL] = %s%n",nameSegment,levelStr);
            int level = getLevelId(nameSegment + ".LEVEL",levelStr);
            if (level != (-1))
            {
                return level;
            }
    
            // Trim and try again.
            int idx = nameSegment.lastIndexOf('.');
            if (idx >= 0)
            {
                nameSegment = nameSegment.substring(0,idx);
            }
            else
            {
                nameSegment = null;
            }
        }
    
        // Default Logging Level
        return LEVEL_DEFAULT;
    }


    public static String getLoggingProperty(Properties props, String name, String property)
    {
        // Calculate the level this named logger should operate under.
        // Checking with FQCN first, then each package segment from longest to shortest.
        String nameSegment = name;
    
        while ((nameSegment != null) && (nameSegment.length() > 0))
        {
            String s = props.getProperty(nameSegment+"."+property);
            if (s!=null)
                return s;
    
            // Trim and try again.
            int idx = nameSegment.lastIndexOf('.');
            nameSegment = (idx >= 0)?nameSegment.substring(0,idx):null;
        }
    
        return null;
    }


    protected static int getLevelId(String levelSegment, String levelName)
    {
        if (levelName == null)
        {
            return -1;
        }
        String levelStr = levelName.trim();
        if ("ALL".equalsIgnoreCase(levelStr))
        {
            return LEVEL_ALL;
        }
        else if ("DEBUG".equalsIgnoreCase(levelStr))
        {
            return LEVEL_DEBUG;
        }
        else if ("INFO".equalsIgnoreCase(levelStr))
        {
            return LEVEL_INFO;
        }
        else if ("WARN".equalsIgnoreCase(levelStr))
        {
            return LEVEL_WARN;
        }
        else if ("OFF".equalsIgnoreCase(levelStr))
        {
            return LEVEL_OFF;
        }
    
        System.err.println("Unknown StdErrLog level [" + levelSegment + "]=[" + levelStr + "], expecting only [ALL, DEBUG, INFO, WARN, OFF] as values.");
        return -1;
    }


    /**
     * Condenses a classname by stripping down the package name to just the first character of each package name
     * segment.Configured
     *
     * <pre>
     * Examples:
     * "org.eclipse.jetty.test.FooTest"           = "oejt.FooTest"
     * "org.eclipse.jetty.server.logging.LogTest" = "orjsl.LogTest"
     * </pre>
     *
     * @param classname
     *            the fully qualified class name
     * @return the condensed name
     */
    protected static String condensePackageString(String classname)
    {
        String parts[] = classname.split("\\.");
        StringBuilder dense = new StringBuilder();
        for (int i = 0; i < (parts.length - 1); i++)
        {
            dense.append(parts[i].charAt(0));
        }
        if (dense.length() > 0)
        {
            dense.append('.');
        }
        dense.append(parts[parts.length - 1]);
        return dense.toString();
    }


    public void debug(String msg, long arg)
    {
        if (isDebugEnabled())
        {
            debug(msg,new Object[] { new Long(arg) });
        }
    }
}
