/*
 * Copyright (C) 2002 - 2022 ScalAgent Distributed Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA.
 *
 * Original developer: ScalAgent Distributed Technologies
 * Contributor(s): Douglas S. Jackson
 */
package fr.dyade.aaa.common;

import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Level;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.LoggingFactory;

/**
 * This class handles the debug traces.
 */
public final class Debug {
  /** flag used to remove huge logging */
  public final static boolean debug = true;

  /**
   * Property name for A3 debug configuration directory.
   * If not defined, the configuration file is searched from the search path used to load classes.
   */
  public final static String DEBUG_DIR_PROPERTY = "fr.dyade.aaa.DEBUG_DIR";
  /** Property name for A3 debug configuration filename */
  public final static String DEBUG_FILE_PROPERTY = "fr.dyade.aaa.DEBUG_FILE";
  /** Default filename for A3 debug configuration */
  public final static String DEFAULT_DEBUG_FILE = "a3debug.cfg";

  /** Property name for LoggerFactory classname */
  public final static String DEBUG_LOGGING_FACTORY_PROPERTY = "fr.dyade.aaa.DEBUG_LOGGING_FACTORY";
  /** Default LoggerFactory classname */
  public final static String DEFAULT_DEBUG_LOGGING_FACTORY = "org.objectweb.util.monolog.jul.SimpleLoggingFactory";
  
  /** */
  private static LoggingFactory factory;

  protected static void init() {
    try {
      // Configures the underlying logging framework.
      String lfcn = System.getProperty(DEBUG_LOGGING_FACTORY_PROPERTY, DEFAULT_DEBUG_LOGGING_FACTORY);
      Class<?> fclass = Class.forName(lfcn);
      factory = (LoggingFactory) fclass.newInstance();

      String debugDir = System.getProperty(Debug.DEBUG_DIR_PROPERTY);
      String debugFileName = System.getProperty(Debug.DEBUG_FILE_PROPERTY, Debug.DEFAULT_DEBUG_FILE);
      
      // Initializes BasicLevel class with Monolog levels.
      BasicLevel.initialize(factory);
      factory.initialize(debugDir, debugFileName);
    } catch(Exception exc) {
      System.err.println("Monolog configuration file not found, use defaults");
      exc.printStackTrace();
      
      factory = new LoggingFactory() {
        Logger logger = new Logger() {

          @Override
          public void setLevel(Level level) {}

          @Override
          public void setLevel(String level) throws Exception {}

          @Override
          public boolean isLoggable(Level level) {
            return true;
          }

          @Override
          public void log(Level level, String msg) {
            System.err.println(msg);
          }

          @Override
          public void log(Level level, String msg, Throwable t) {
            System.err.println(msg);
            exc.printStackTrace();
          }

          @Override
          public void log(Level level, String msg, Object param1) {
            System.err.println(msg);
          }

          @Override
          public void log(Level level, String msg, Object[] params) {
            System.err.println(msg);
          }

          @Override
          public String getName() {
            return "PrivateLogger";
          }
        };
        
        Level level = new Level() {
          @Override
          public int intValue() {
            return 0;
          }
        };
        
        @Override
        public void initialize(String debugDir, String debugFileName) {}

        @Override
        public Logger getLogger(String topic) {
          return logger;
        }

        @Override
        public Level getFatalLevel() {
          return level;
        }

        @Override
        public Level getErrorLevel() {
          return level;
        }

        @Override
        public Level getWarnLevel() {
          return level;
        }

        @Override
        public Level getInfoLevel() {
          return level;
        }

        @Override
        public Level getDebugLevel() {
          return level;
        }

        @Override
        public Level parse(String name) {
          return level;
        }
      };
      
      // Initializes BasicLevel class with Monolog levels.
      BasicLevel.initialize(factory);
      factory.initialize(null, null);
    }
  }

  public static Logger getLogger(String topic) {
    if (factory == null) init();
    Logger logger = factory.getLogger(topic);
    return logger;
  }

  /**
   * Set the Monolog Loggerfactory
   * @param loggerFactory the monolog LoggerFactory
   */
  @Deprecated
  public static void setLoggerFactory(LoggingFactory loggerFactory) {
    // TODO (AF): Normally no longer used, to remove in 5.20 release.
//    logManager = loggerFactory;
  }

  public static void setDebugLevel(String classname) {
    getLogger(classname).setLevel(BasicLevel.DEBUG);
  }

  public static void setInfoLevel(String classname) {
    getLogger(classname).setLevel(BasicLevel.INFO);
  }

  public static void setWarnLevel(String classname) {
    getLogger(classname).setLevel(BasicLevel.WARN);
  }

  public static void setErrorLevel(String classname) {
    getLogger(classname).setLevel(BasicLevel.ERROR);
  }

  public static void setFatalLevel(String classname) {
    getLogger(classname).setLevel(BasicLevel.FATAL);
  }
  
  public static void setLoggerLevel(String classname, String level) throws Exception {
    getLogger(classname).setLevel(level);
  }

  public static void clearLevel(String classname) {
    getLogger(classname).setLevel((Level) null);
  }
}
