/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.component.jmx;

import java.lang.management.ManagementFactory;
import java.util.UUID;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.NotificationFilter;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.monitor.CounterMonitor;
import javax.management.monitor.GaugeMonitor;
import javax.management.monitor.Monitor;
import javax.management.monitor.StringMonitor;

import org.apache.camel.Processor;

/**
 * Variant of the consumer that creates and registers a monitor bean to 
 * monitor object and attribute referenced by the endpoint. The only 
 * difference here is the act of adding and removing the notification
 * listener.
 */
public class JMXMonitorConsumer extends JMXConsumer {
    
    /** name of our monitor. We keep a reference since it needs to be removed when we stop listening */
    ObjectName mMonitorObjectName;

    public JMXMonitorConsumer(JMXEndpoint aEndpoint, Processor aProcessor) {
        super(aEndpoint, aProcessor);
    }

    @Override
    protected void addNotificationListener() throws Exception {
        
        JMXEndpoint ep = getEndpoint();
        // create the monitor bean
        Monitor bean = null;
        if (ep.getMonitorType().equals("counter")) {
            CounterMonitor counter = new CounterMonitor();
            Number initThreshold = convertNumberToAttributeType(ep.getInitThreshold(), ep.getJMXObjectName(), ep.getObservedAttribute());
            Number offset = convertNumberToAttributeType(ep.getOffset(), ep.getJMXObjectName(), ep.getObservedAttribute());
            Number modulus = convertNumberToAttributeType(ep.getModulus(), ep.getJMXObjectName(), ep.getObservedAttribute());
            counter.setInitThreshold(initThreshold);
            counter.setOffset(offset);
            counter.setModulus(modulus);
            counter.setDifferenceMode(ep.isDifferenceMode());
            counter.setNotify(true);
            bean = counter;
        } else if (ep.getMonitorType().equals("gauge")) {
            GaugeMonitor gm = new GaugeMonitor();
            gm.setNotifyHigh(ep.isNotifyHigh());
            gm.setNotifyLow(ep.isNotifyLow());
            gm.setDifferenceMode(ep.isDifferenceMode());
            Number highValue = convertNumberToAttributeType(ep.getThresholdHigh(), ep.getJMXObjectName(), ep.getObservedAttribute());
            Number lowValue = convertNumberToAttributeType(ep.getThresholdLow(), ep.getJMXObjectName(), ep.getObservedAttribute());
            gm.setThresholds(highValue, lowValue);
            bean = gm;
        } else if (ep.getMonitorType().equals("string")) {
            StringMonitor sm = new StringMonitor();
            sm.setNotifyDiffer(ep.isNotifyDiffer());
            sm.setNotifyMatch(ep.isNotifyMatch());
            sm.setStringToCompare(ep.getStringToCompare());
            bean = sm;
        } else {
            throw new IllegalArgumentException("Unsupported monitortype: " + ep.getMonitorType());
        }
        
        bean.addObservedObject(ep.getJMXObjectName());
        bean.setObservedAttribute(ep.getObservedAttribute());
        bean.setGranularityPeriod(ep.getGranularityPeriod());

        // register the bean
        mMonitorObjectName = new ObjectName(ep.getObjectDomain(), "name", "camel-jmx-monitor-" + UUID.randomUUID());
        ManagementFactory.getPlatformMBeanServer().registerMBean(bean, mMonitorObjectName); 
        
        // add ourselves as a listener to it
        NotificationFilter nf = ep.getNotificationFilter();
        getServerConnection().addNotificationListener(mMonitorObjectName, this, nf, bean);
        bean.start();
    }

    @Override
    protected void removeNotificationListeners() throws Exception {
        // remove ourselves as a listener
        ManagementFactory.getPlatformMBeanServer().removeNotificationListener(mMonitorObjectName, this);
        // unregister the monitor bean
        ManagementFactory.getPlatformMBeanServer().unregisterMBean(mMonitorObjectName);
    }

    private Number convertNumberToAttributeType(Number toConvert, ObjectName jmxObjectName, String observedAttribute)
        throws InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
        Object attr = ManagementFactory.getPlatformMBeanServer().getAttribute(jmxObjectName, observedAttribute);
        if (attr instanceof Byte) {
            return toConvert != null ? toConvert.byteValue() : null;
        } else if (attr instanceof Integer) {
            return toConvert != null ? toConvert.intValue() : null;
        } else if (attr instanceof Short) {
            return toConvert != null ? toConvert.shortValue() : null;
        } else if (attr instanceof Long) {
            return toConvert != null ? toConvert.longValue() : null;
        } else if (attr instanceof Float) {
            return toConvert != null ? toConvert.floatValue() : null;
        } else {
            return toConvert;
        }
    }
}
