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

import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;


/** 
 * Hardcoded java.util.logging commons-logging implementation.
 * 
 * In addition, it curr 
 * 
 */
class DirectJDKLog implements Log {
    // no reason to hide this - but good reasons to not hide
    public Logger logger;
    
    /** Alternate config reader and console format 
     */
    private static final String SIMPLE_FMT="org.apache.tomcat.util.log.JdkLoggerFormatter";
    private static final String SIMPLE_CFG="org.apache.tomcat.util.log.JdkLoggerConfig";

    static {
        if( System.getProperty("java.util.logging.config.class") ==null  &&
                System.getProperty("java.util.logging.config.file") ==null ) {
            // default configuration - it sucks. Let's override at least the 
            // formatter for the console
            try {
                Class.forName(SIMPLE_CFG).newInstance();                
            } catch( Throwable t ) {                
            }
            try {
                Formatter fmt=(Formatter)Class.forName(SIMPLE_FMT).newInstance();
                // it is also possible that the user modifed jre/lib/logging.properties - 
                // but that's really stupid in most cases
                Logger root=Logger.getLogger("");
                Handler handlers[]=root.getHandlers();
                for( int i=0; i< handlers.length; i++ ) {
                    // I only care about console - that's what's used in default config anyway
                    if( handlers[i] instanceof  ConsoleHandler ) {
                        handlers[i].setFormatter(fmt);
                    }
                }
            } catch( Throwable t ) {
                // maybe it wasn't included - the ugly default will be used.
            }
            
        }
    }
    
    public DirectJDKLog(String name ) {
        logger=Logger.getLogger(name);        
    }
    
    public final boolean isErrorEnabled() {
        return logger.isLoggable(Level.SEVERE);
    }
    
    public final boolean isWarnEnabled() {
        return logger.isLoggable(Level.WARNING); 
    }
    
    public final boolean isInfoEnabled() {
        return logger.isLoggable(Level.INFO);
    }
    
    public final boolean isDebugEnabled() {
        return logger.isLoggable(Level.FINE);
    }
    
    public final boolean isFatalEnabled() {
        return logger.isLoggable(Level.SEVERE);
    }
    
    public final boolean isTraceEnabled() {
        return logger.isLoggable(Level.FINER);
    }
    
    public final void debug(Object message) {
        log(Level.FINE, String.valueOf(message), null);
    }
    
    public final void debug(Object message, Throwable t) {
        log(Level.FINE, String.valueOf(message), t);
    }
    
    public final void trace(Object message) {
        log(Level.FINER, String.valueOf(message), null);
    }
    
    public final void trace(Object message, Throwable t) {
        log(Level.FINER, String.valueOf(message), t);
    }
    
    public final void info(Object message) {
        log(Level.INFO, String.valueOf(message), null);
    }
    
    public final void info(Object message, Throwable t) {        
        log(Level.INFO, String.valueOf(message), t);
    }
    
    public final void warn(Object message) {
        log(Level.WARNING, String.valueOf(message), null);
    }
    
    public final void warn(Object message, Throwable t) {
        log(Level.WARNING, String.valueOf(message), t);
    }
    
    public final void error(Object message) {
        log(Level.SEVERE, String.valueOf(message), null);
    }
    
    public final void error(Object message, Throwable t) {
        log(Level.SEVERE, String.valueOf(message), t);
    }
    
    public final void fatal(Object message) {
        log(Level.SEVERE, String.valueOf(message), null);
    }
    
    public final void fatal(Object message, Throwable t) {
        log(Level.SEVERE, String.valueOf(message), t);
    }    

    // from commons logging. This would be my number one reason why java.util.logging
    // is bad - design by comitee can be really bad ! The impact on performance of 
    // using java.util.logging - and the ugliness if you need to wrap it - is far
    // worse than the unfriendly and uncommon default format for logs. 
    
    private void log( Level level, String msg, Throwable ex ) {
        if (logger.isLoggable(level)) {
            // Hack (?) to get the stack trace.
            Throwable dummyException=new Throwable();
            StackTraceElement locations[]=dummyException.getStackTrace();
            // Caller will be the third element
            String cname="unknown";
            String method="unknown";
            if( locations!=null && locations.length >2 ) {
                StackTraceElement caller=locations[2];
                cname=caller.getClassName();
                method=caller.getMethodName();
            }
            if( ex==null ) {
                logger.logp( level, cname, method, msg );
            } else {
                logger.logp( level, cname, method, msg, ex );
            }
        }
    }        

    // for LogFactory
    static void release() {
        
    }
    
    static Log getInstance(String name) {
        return new DirectJDKLog( name );
    }
}


