/* JFox, the OpenSource J2EE Application Server
 *
 * Copyright (C) 2002 huihoo.org
 * Distributable under GNU LGPL license
 * See the GNU Lesser General Public License for more details.
 */

package org.huihoo.jfox.logging;

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;
import org.jfox.mx.Mxable;

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

public class LogMX implements Mxable {
  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(LogMX.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;
  }
}