// 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 com.cloud.consoleproxy.util;

// logger facility for dynamic switch between console logger used in Applet and log4j based logger
public class Logger {
    private static LoggerFactory factory = null;
    
    public static final int LEVEL_TRACE = 1;
    public static final int LEVEL_DEBUG = 2;
    public static final int LEVEL_INFO = 3;
    public static final int LEVEL_WARN = 4;
    public static final int LEVEL_ERROR = 5;
    
    private Class<?> clazz;
    private Logger logger;
    
    private static int level = LEVEL_INFO;
    
    public static Logger getLogger(Class<?> clazz) {
        return new Logger(clazz);
    }
    
    public static void setFactory(LoggerFactory f) {
        factory = f;
    }
    
    public static void setLevel(int l) {
        level = l;
    }
    
    public Logger(Class<?> clazz) {
        this.clazz = clazz;
    }
    
    protected Logger() {
    }
    
    public boolean isTraceEnabled() {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            return logger.isTraceEnabled();
        }
        return level <= LEVEL_TRACE;
    }
    
    public boolean isDebugEnabled() {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            return logger.isDebugEnabled();
        }
        return level <= LEVEL_DEBUG;
    }
    
    public boolean isInfoEnabled() {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            return logger.isInfoEnabled();
        }
        return level <= LEVEL_INFO;
    }

    public void trace(Object message) {
        
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.trace(message);
        } else {
            if(level <= LEVEL_TRACE)
                System.out.println(message);
        }
    }
    
    public void trace(Object message, Throwable exception) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.trace(message, exception);
        } else {
            if(level <= LEVEL_TRACE) {
                System.out.println(message);
                if (exception != null) {
                    exception.printStackTrace(System.out);
                }
            }
        }
    }
    
    public void info(Object message) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.info(message);
        } else {
            if(level <= LEVEL_INFO)
                System.out.println(message);
        }
    }
    
    public void info(Object message, Throwable exception) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.info(message, exception);
        } else {        
            if(level <= LEVEL_INFO) {
                System.out.println(message);
                if (exception != null) {
                    exception.printStackTrace(System.out);
                }
            }
        }
    }
    
    public void debug(Object message) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.debug(message);
        } else {
            if(level <= LEVEL_DEBUG)
                System.out.println(message);
        }
    }
    
    public void debug(Object message, Throwable exception) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.debug(message, exception);
        } else {
            if(level <= LEVEL_DEBUG) {
                System.out.println(message);
                if (exception != null) {
                    exception.printStackTrace(System.out);
                }
            }
        }
    }
    
    public void warn(Object message) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.warn(message);
        } else {
            if(level <= LEVEL_WARN)
                System.out.println(message);
        }
    }
    
    public void warn(Object message, Throwable exception) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.warn(message, exception);
        } else {
            if(level <= LEVEL_WARN) {
                System.out.println(message);
                if (exception != null) {
                    exception.printStackTrace(System.out);
                }
            }
        }
    }
    
    public void error(Object message) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.error(message);
        } else {
            if(level <= LEVEL_ERROR)
                System.out.println(message);
        }
    }
    
    public void error(Object message, Throwable exception) {
        if(factory != null) {
            if(logger == null)
                logger = factory.getLogger(clazz);
            
            logger.error(message, exception);
        } else {
            if(level <= LEVEL_ERROR) {
                System.out.println(message);
                if (exception != null) {
                    exception.printStackTrace(System.out);
                }
            }
        }
    }
}
