/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2007 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * 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 (at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.lib.jmbeans;

import java.util.Properties;
import java.util.TreeSet;

import org.objectweb.util.monolog.api.Level;
import org.objectweb.util.monolog.api.Logger;
import org.ow2.jonas.lib.management.javaee.J2EEManagedObject;
import org.ow2.jonas.lib.management.reconfig.PropertiesConfigurationData;
import org.ow2.jonas.lib.util.Log;

/**
 * LogManager defined as a J2EEManagedObject sub-class in order to
 * use JMX notification support.
 * @author Adriana.Danes@bull.net
 */
public class LogManager extends J2EEManagedObject {

    /**
     * Log service name.
     */
    private static String SERVICE_NAME = "log";

    /**
     * Constructor.
     * @param objectName The MBean's OBJECT_NAME
     */
    public LogManager(final String objectName) {
        super(objectName);
    }

    /**
     *  Needed to send JMX notifications.
     */
    private long sequenceNumber = 0;

    /**
     * Configuration properties.
     */
    private Properties props = null;

    /**
     * Configuration file name.
     */
    private String configFile = null;
    /**
     * Get the topics list. Assumes that all Loggers are TopicalLoggers.
     * @return the topics list.
     */
    public String[] getTopics() {
        Logger[] logs = Log.getLoggerFactory().getLoggers();
        // put names in alphabetical order
        TreeSet<String> tset = new TreeSet<String>();
        for (int i = 0; i < logs.length; i++) {
            tset.add(logs[i].getName());
        }
        return tset.toArray(new String[0]);
    }

    /**
     * Return a topic's level.
     * @param topic the topic we need to know its level
     * @return the topic's level
     */
    public String getTopicLevel(final String topic) {
        Logger topicLogger = Log.getLoggerFactory().getLogger(topic);
        Level lev = topicLogger.getCurrentLevel();
        return lev.getName();
    }

    /**
     * set Topic Level
     * @param topic topic to set
     * @param level the level to set
     */
    public void setTopicLevel(final String topic, final String level) {
        Logger topicLogger = Log.getLoggerFactory().getLogger(topic);
        Level lev = Log.getLevelFactory().getLevel(level);
        // must check null (bug monolog)
        if (lev != null) {
            topicLogger.setLevel(lev);
        } else {
            // TO DO maybe a better error treatement could be found
            throw new RuntimeException("Unknown level " + level);
        }
        // the modified property name is 'logger.topic.level'
        String propName = "logger." + topic + ".level";
        // Send a notification containing the new value of this property to the
        // listener MBean
        sendReconfigNotification(++sequenceNumber, SERVICE_NAME, new PropertiesConfigurationData(propName, level));
    }

    /**
     * Save updated configuration.
     */
    public void saveConfig() {
        sendSaveNotification(++sequenceNumber, SERVICE_NAME);
    }

    /**
     * @return Configuration properties
     */
    public Properties getProps() {
        return props;
    }

    /**
     * @param props Configuration properties
     */
    public void setProps(final Properties props) {
        this.props = props;
    }

    /**
     * @return Configuration file name
     */
    public String getConfigFile() {
        return configFile;
    }

    /**
     * @param configFile Configuration file name
     */
    public void setConfigFile(final String configFile) {
        this.configFile = configFile;
    }

}
