/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.  */

package org.apache.log4j.jmx;


import java.lang.reflect.Constructor;
import org.apache.log4j.*;

import org.apache.log4j.spi.LoggerEventListener;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.helpers.OptionConverter;

import java.util.Vector;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;

import javax.management.ObjectName;
import javax.management.MBeanInfo;
import javax.management.Attribute;

import javax.management.MBeanException;
import javax.management.AttributeNotFoundException;
import javax.management.RuntimeOperationsException;
import javax.management.ReflectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationBroadcaster;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.NotificationFilter;
import javax.management.NotificationFilterSupport;
import javax.management.ListenerNotFoundException;

public class HierarchyDynamicMBean extends AbstractDynamicMBean
                                   implements LoggerEventListener,
                                              NotificationBroadcaster {

  static final String ADD_APPENDER = "addAppender.";
  static final String THRESHOLD = "threshold";

  private MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[1];
  private MBeanOperationInfo[] dOperations = new MBeanOperationInfo[1];

  private Vector vAttributes = new Vector();
  private String dClassName = this.getClass().getName();
  private String dDescription =
     "This MBean acts as a management facade for org.apache.log4j.Hierarchy.";

  private NotificationBroadcasterSupport nbs = new NotificationBroadcasterSupport();


  private LoggerRepository hierarchy;

  private static Logger log = Logger.getLogger(HierarchyDynamicMBean.class);

  public HierarchyDynamicMBean() {
    hierarchy = LogManager.getLoggerRepository();
    buildDynamicMBeanInfo();
  }

  private
  void buildDynamicMBeanInfo() {
    Constructor[] constructors = this.getClass().getConstructors();
    dConstructors[0] = new MBeanConstructorInfo(
         "HierarchyDynamicMBean(): Constructs a HierarchyDynamicMBean instance",
	 constructors[0]);

    vAttributes.add(new MBeanAttributeInfo(THRESHOLD,
					   "java.lang.String",
					   "The \"threshold\" state of the hiearchy.",
					   true,
					   true,
					   false));

    MBeanParameterInfo[] params = new MBeanParameterInfo[1];
    params[0] = new MBeanParameterInfo("name", "java.lang.String",
				       "Create a logger MBean" );
    dOperations[0] = new MBeanOperationInfo("addLoggerMBean",
				    "addLoggerMBean(): add a loggerMBean",
				    params ,
				    "javax.management.ObjectName",
				    MBeanOperationInfo.ACTION);
  }


  public
  ObjectName addLoggerMBean(String name) {
    Logger cat = LogManager.exists(name);

    if(cat != null) {
      return addLoggerMBean(cat);
    } else {
      return null;
    }
  }

  ObjectName addLoggerMBean(Logger logger) {
    String name = logger.getName();
    ObjectName objectName = null;
    try {
      LoggerDynamicMBean loggerMBean = new LoggerDynamicMBean(logger);
      objectName = new ObjectName("log4j", "logger", name);
      server.registerMBean(loggerMBean, objectName);

      NotificationFilterSupport nfs = new NotificationFilterSupport();
      nfs.enableType(ADD_APPENDER+logger.getName());

      log.debug("---Adding logger ["+name+"] as listener.");

      nbs.addNotificationListener(loggerMBean, nfs, null);


      vAttributes.add(new MBeanAttributeInfo("logger="+name,
					     "javax.management.ObjectName",
					     "The "+name+" logger.",
					     true,
					     true, // this makes the object
					     // clickable
					     false));

    } catch(Exception e) {
      log.error("Couls not add loggerMBean for ["+name+"].");
    }
    return objectName;
  }

  public
  void addNotificationListener(NotificationListener listener,
			       NotificationFilter filter,
			       java.lang.Object handback) {
    nbs.addNotificationListener(listener, filter, handback);
  }

  protected
  Logger getLogger() {
    return log;
  }

  public
  MBeanInfo getMBeanInfo() {
    //cat.debug("getMBeanInfo called.");

    MBeanAttributeInfo[] attribs = new MBeanAttributeInfo[vAttributes.size()];
    vAttributes.toArray(attribs);

    return new MBeanInfo(dClassName,
			 dDescription,
			 attribs,
			 dConstructors,
			 dOperations,
			 new MBeanNotificationInfo[0]);
  }

  public
  MBeanNotificationInfo[] getNotificationInfo(){
    return nbs.getNotificationInfo();
  }

  public
  Object invoke(String operationName,
		Object params[],
		String signature[]) throws MBeanException,
                                           ReflectionException {

    if (operationName == null) {
      throw new RuntimeOperationsException(
        new IllegalArgumentException("Operation name cannot be null"),
	"Cannot invoke a null operation in " + dClassName);
    }
    // Check for a recognized operation name and call the corresponding operation

    if(operationName.equals("addLoggerMBean")) {
      return addLoggerMBean((String)params[0]);
    } else {
      throw new ReflectionException(
	    new NoSuchMethodException(operationName),
	    "Cannot find the operation " + operationName + " in " + dClassName);
    }

  }


  public
  Object getAttribute(String attributeName) throws AttributeNotFoundException,
                                                    MBeanException,
                                                    ReflectionException {

    // Check attributeName is not null to avoid NullPointerException later on
    if (attributeName == null) {
      throw new RuntimeOperationsException(new IllegalArgumentException(
			"Attribute name cannot be null"),
       "Cannot invoke a getter of " + dClassName + " with null attribute name");
    }

    log.debug("Called getAttribute with ["+attributeName+"].");

    // Check for a recognized attributeName and call the corresponding getter
    if (attributeName.equals(THRESHOLD)) {
      return hierarchy.getThreshold();
    } else if(attributeName.startsWith("logger")) {
      int k = attributeName.indexOf("%3D");
      String val = attributeName;
      if(k > 0) {
	val = attributeName.substring(0, k)+'='+ attributeName.substring(k+3);
      }
      try {
	return new ObjectName("log4j:"+val);
      } catch(Exception e) {
	log.error("Could not create ObjectName" + val);
      }
    }



    // If attributeName has not been recognized throw an AttributeNotFoundException
    throw(new AttributeNotFoundException("Cannot find " + attributeName +
					 " attribute in " + dClassName));

  }


  public void appenderAddedEvent(Logger logger, Appender appender) {
    log.debug("addAppenderEvent called: logger="+logger.getName()+
	      ", appender="+appender.getName());
    Notification n = new Notification(ADD_APPENDER+logger.getName(), this, 0);
    n.setUserData(appender);
    log.debug("sending notification.");
    nbs.sendNotification(n);
  }

 public void appenderRemovedEvent(Logger logger, Appender appender) {
    log.debug("removeAppenderCalled: logger="+logger.getName()+
	      ", appender="+appender.getName());
  }

  public void levelChangedEvent(Logger logger) {
    // FIX ME
    // FIX ME
  }

  public
  void postRegister(java.lang.Boolean registrationDone) {
    log.debug("postRegister is called.");
    hierarchy.addLoggerEventListener(this);
    Logger root = hierarchy.getRootLogger();
    addLoggerMBean(root);
  }

  public
  void removeNotificationListener(NotificationListener listener)
                                         throws ListenerNotFoundException {
    nbs.removeNotificationListener(listener);
  }

  public
  void setAttribute(Attribute attribute) throws AttributeNotFoundException,
                                                InvalidAttributeValueException,
                                                MBeanException,
                                                ReflectionException {

    // Check attribute is not null to avoid NullPointerException later on
    if (attribute == null) {
      throw new RuntimeOperationsException(
                  new IllegalArgumentException("Attribute cannot be null"),
	  "Cannot invoke a setter of "+dClassName+" with null attribute");
    }
    String name = attribute.getName();
    Object value = attribute.getValue();

    if (name == null) {
      throw new RuntimeOperationsException(
               new IllegalArgumentException("Attribute name cannot be null"),
	       "Cannot invoke the setter of "+dClassName+
	       " with null attribute name");
    }

    if(name.equals(THRESHOLD)) {
      Level l = OptionConverter.toLevel((String) value,
					   hierarchy.getThreshold());
      hierarchy.setThreshold(l);
    }


  }
}
