/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */
package org.jfox.framework.logger;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Appender;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.RollingFileAppender;

/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class LoggerMananger {
    private static org.apache.log4j.Logger rootLogger = LogManager.getRootLogger();
    private static final String configFile = "log4j.properties";

    static {
        _init();
    }

    static void _init() {
        URL url = Thread.currentThread().getContextClassLoader().getResource(configFile);
        if(url != null) {
            PropertyConfigurator.configureAndWatch(configFile, 1000);
        }
        else {
            Appender app = new ConsoleAppender(new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN));
            app.setName("console");
            rootLogger.addAppender(app);
        }
//    rootLogger.setLevel(Level.INFO);
        rootLogger.info(LoggerMananger.class.getName() + " initialized.");
    }

    public void mx_reset() {
        org.apache.log4j.LogManager.resetConfiguration();
        _init();
    }

    public void mx_setLevel(String loggerName, String level) {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        logger.setLevel(Level.toLevel(level));
    }

    public String mx_getLevel(String loggerName) {
        org.apache.log4j.Logger logger = getLogger(loggerName);

        Level level = logger.getLevel();
        if(level == null) {
            return null;
        }
        else {
            return level.toString();
        }
    }

    public void mx_setPattern(String loggerName, String appenderName, String pattern) {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        Appender appender = logger.getAppender(appenderName);
        if(appender != null) {
            appender.setLayout(new PatternLayout(pattern));
        }
    }

    public String mx_getPattern(String loggerName, String appenderName) {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        Appender appender = logger.getAppender(appenderName);
        if(appender != null) {
            Layout layout = appender.getLayout();
            if((layout != null) && (layout instanceof PatternLayout)) {
                return ((PatternLayout) layout).getConversionPattern();
            }
        }
        return "";
    }

    public void mx_addFileAppender(String loggerName, String appenderName, String pattern, String filename) throws IOException {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        FileAppender fa = new FileAppender(new PatternLayout(pattern), filename);
//    fa.setBufferedIO(true);
        fa.setName(appenderName);
        logger.addAppender(fa);
    }

    public void mx_addRollingFileAppender(String loggerName, String appenderName, String pattern, String filename, String maxFileSize) throws IOException {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        RollingFileAppender rfa = new RollingFileAppender(new PatternLayout(pattern), filename);
//    fa.setBufferedIO(true);
        rfa.setName(appenderName);
        rfa.setMaxFileSize(maxFileSize);
        logger.addAppender(rfa);
    }

    public void mx_addDailyRollingFileAppender(String loggerName, String appenderName, String pattern, String filename) throws IOException {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        DailyRollingFileAppender drfa = new DailyRollingFileAppender(new PatternLayout(pattern), filename, "'.'yyyy-MM");
        drfa.setName(appenderName);
        logger.addAppender(drfa);
    }


    public void mx_removeAppender(String loggerName, String appenderName) {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        logger.removeAppender(appenderName);
    }


    public List mx_getAllApenders(String loggerName) {
        org.apache.log4j.Logger logger = getLogger(loggerName);
        Enumeration enu = logger.getAllAppenders();
        List appenders = new ArrayList();
        while(enu.hasMoreElements()) {
            appenders.add(enu.nextElement());
        }
        return appenders;
    }

    public Properties getOperationDescriptions() {
        Properties prop = new Properties();
        prop.setProperty("mx_getPattern", " mx_getPattern(String loggerName,String appenderName), parameter example: root, console");
        prop.setProperty("mx_getLevel", "get level by Logger name, exsample: root");
        prop.setProperty("mx_setLevel", "mx_setLevel(String loggerName, String level)");
        prop.setProperty("mx_addFileAppender", "mx_addFileAppender(String loggerName,String appenderName, String pattern, String filename)");
        prop.setProperty("mx_addRollingFileAppender", "mx_addRollingFileAppender(String loggerName,String appenderName, String pattern, String filename,String maxFileSize)");
        prop.setProperty("mx_addDailyRollingFileAppender", "mx_addDailyRollingFileAppender(String loggerName,String appenderName, String pattern, String filename)");
        prop.setProperty("mx_removeAppender", "mx_removeAppender(String loggerName, String appenderName)");
        prop.setProperty("mx_getAllApenders", "mx_getAllApenders(String loggerName)");
        prop.setProperty("mx_setPattern", "mx_setPattern(String loggerName, String appenderName, String pattern)");
        return prop;
    }

    public Object getSource() {
        return this;
    }

    public String getMxDescription() {
        return "Logger Manager";
    }

    private org.apache.log4j.Logger getLogger(String name) {
        org.apache.log4j.Logger logger;
        if(name.equals("root")) {
            logger = rootLogger;
        }
        else {
            logger = org.apache.log4j.Logger.getLogger(name);
        }
        return logger;
    }

}

