/*
 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This source code is provided to illustrate the usage of a given feature
 * or technique and has been deliberately simplified. Additional steps
 * required for a production-quality application, such as security checks,
 * input validation and proper error handling, might not be present in
 * this sample code.
 */

/*
 * This is a collection of utilities for Monitoring
 * and management API.
 *
 * File dependency:
 *    conc.js -> for concurrency utilities
 */

// At any time, we maintain atmost one MBeanServer
// connection. And so, we store the same as a global
// variable.
var mmConnection = null;

function jmxConnect(hostport) {
    if (mmConnection != null) {
        // close the existing connection
        try {
            mmConnection.close();
        } catch (e) {
        }
    }

    var JMXServiceURL = javax.management.remote.JMXServiceURL;
    var JMXConnectorFactory = javax.management.remote.JMXConnectorFactory;

    var urlPath = "/jndi/rmi://" + hostport + "/jmxrmi";
    var url = new JMXServiceURL("rmi", "", 0, urlPath);
    var jmxc = JMXConnectorFactory.connect(url);
    // note that the "mmConnection" is a global variable!
    mmConnection = jmxc.getMBeanServerConnection();
}
jmxConnect.docString = "connects to the given host, port (specified as name:port)";

function mbeanConnection() {
    if (mmConnection == null) {
        throw "Not connected to MBeanServer yet!";
    }

    return mmConnection;
}
mbeanConnection.docString = "returns the current MBeanServer connection";

/**
 * Returns a platform MXBean proxy for given MXBean name and interface class
 */
function newPlatformMXBeanProxy(name, intf) {
    var factory = java.lang.management.ManagementFactory;
    return factory.newPlatformMXBeanProxy(mbeanConnection(), name, intf);
}
newPlatformMXBeanProxy.docString = "returns a proxy for a platform MXBean";

/**
 * Wraps a string to ObjectName if needed.
 */
function objectName(objName) {
    var ObjectName = Packages.javax.management.ObjectName;
    if (objName instanceof ObjectName) {
        return objName;
    } else {
        return new ObjectName(objName);
    }
}
objectName.docString = "creates JMX ObjectName for a given String";

/**
 * Creates a new (M&M) Attribute object
 *
 * @param name name of the attribute
 * @param value value of the attribute
 */
function attribute(name, value) {
    var Attribute = Packages.javax.management.Attribute;
    return new Attribute(name, value);
}
attribute.docString = "returns a new JMX Attribute using name and value given";

/**
 * Returns MBeanInfo for given ObjectName. Strings are accepted.
 */
function mbeanInfo(objName) {
    objName = objectName(objName);
    return mbeanConnection().getMBeanInfo(objName);
}
mbeanInfo.docString = "returns MBeanInfo of a given ObjectName";

/**
 * Returns ObjectInstance for a given ObjectName.
 */
function objectInstance(objName) {
    objName = objectName(objName);
    return mbeanConnection().objectInstance(objectName);
}
objectInstance.docString = "returns ObjectInstance for a given ObjectName";

/**
 * Queries with given ObjectName and QueryExp.
 * QueryExp may be null.
 *
 * @return set of ObjectNames.
 */
function queryNames(objName, query) {
    objName = objectName(objName);
    if (query == undefined) query = null;
    return mbeanConnection().queryNames(objName, query);
}
queryNames.docString = "returns QueryNames using given ObjectName and optional query";

/**
 * Queries with given ObjectName and QueryExp.
 * QueryExp may be null.
 *
 * @return set of ObjectInstances.
 */
function queryMBeans(objName, query) {
    objName = objectName(objName);
    if (query == undefined) query = null;
    return mbeanConnection().queryMBeans(objName, query);
}
queryMBeans.docString = "return MBeans using given ObjectName and optional query";

// wraps a script array as java.lang.Object[]
function objectArray(array) {
    return Java.to(array, "java.lang.Object[]");
}

// wraps a script (string) array as java.lang.String[]
function stringArray(array) {
    return Java.to(array, "java.lang.String[]");
}

// script array to Java List
function toAttrList(array) {
    var AttributeList = Packages.javax.management.AttributeList;
    if (array instanceof AttributeList) {
        return array;
    }
    var list = new AttributeList(array.length);
    for (var index = 0; index < array.length; index++) {
        list.add(array[index]);
    }
    return list;
}

// Java Collection (Iterable) to script array
function toArray(collection) {
    if (collection instanceof Array) {
        return collection;
    }
    var itr = collection.iterator();
    var array = new Array();
    while (itr.hasNext()) {
        array[array.length] = itr.next();
    }
    return array;
}

// gets MBean attributes
function getMBeanAttributes(objName, attributeNames) {
    objName = objectName(objName);
    return mbeanConnection().getAttributes(objName,stringArray(attributeNames));
}
getMBeanAttributes.docString = "returns specified Attributes of given ObjectName";

// gets MBean attribute
function getMBeanAttribute(objName, attrName) {
    objName = objectName(objName);
    return mbeanConnection().getAttribute(objName, attrName);
}
getMBeanAttribute.docString = "returns a single Attribute of given ObjectName";

// sets MBean attributes
function setMBeanAttributes(objName, attrList) {
    objName = objectName(objName);
    attrList = toAttrList(attrList);
    return mbeanConnection().setAttributes(objName, attrList);
}
setMBeanAttributes.docString = "sets specified Attributes of given ObjectName";

// sets MBean attribute
function setMBeanAttribute(objName, attrName, attrValue) {
    var Attribute = Packages.javax.management.Attribute;
    objName = objectName(objName);
    mbeanConnection().setAttribute(objName, new Attribute(attrName, attrValue));
}
setMBeanAttribute.docString = "sets a single Attribute of given ObjectName";

// invokes an operation on given MBean
function invokeMBean(objName, operation, params, signature) {
    objName = objectName(objName);
    params = objectArray(params);
    signature = stringArray(signature);
    return mbeanConnection().invoke(objName, operation, params, signature);
}
invokeMBean.docString = "invokes MBean operation on given ObjectName";

/**
 * Wraps a MBean specified by ObjectName as a convenient
 * script object -- so that setting/getting MBean attributes
 * and invoking MBean method can be done with natural syntax.
 *
 * @param objName ObjectName of the MBean
 * @param async asynchornous mode [optional, default is false]
 * @return script wrapper for MBean
 *
 * With async mode, all field, operation access is async. Results
 * will be of type FutureTask. When you need value, call 'get' on it.
 */
function mbean(objName, async) {
    var index;
    objName = objectName(objName);
    var info = mbeanInfo(objName);
    var attrs = info.attributes;
    var attrMap = new Object;
    for (index in attrs) {
        attrMap[attrs[index].name] = attrs[index];
    }
    var opers = info.operations;
    var operMap = new Object;
    for (index in opers) {
        operMap[opers[index].name] = opers[index];
    }

    function isAttribute(name) {
        return name in attrMap;
    }

    function isOperation(name) {
        return name in operMap;
    }

    return new JSAdapter() {
        __has__: function (name) {
            return isAttribute(name) || isOperation(name);
        },
        __get__: function (name) {
            if (isAttribute(name)) {
                if (async) {
                    return getMBeanAttribute.future(objName, name); 
                } else {
                    return getMBeanAttribute(objName, name); 
                }
            } else {
                return undefined;
            }
        },
        __call__: function(name) {
            if (isOperation(name)) {
                var oper = operMap[name];

                var params = [];
                for (var j = 1; j < arguments.length; j++) {
                    params[j-1]= arguments[j];
                }

                var sigs = oper.signature;

                var sigNames = new Array(sigs.length);
                for (var index in sigs) {
                    sigNames[index] = sigs[index].getType();
                }

                if (async) {
                    return invokeMBean.future(objName, name, params, sigNames);
                } else {
                    return invokeMBean(objName, name, params, sigNames);
                }
            } else {
                return undefined;
            }
        },
        __put__: function (name, value) {
            if (isAttribute(name)) {
                if (async) {
                    setMBeanAttribute.future(objName, name, value);
                } else {
                    setMBeanAttribute(objName, name, value);
                }
            } else {
                return undefined;
            }
        }
    };
}
mbean.docString = "returns a conveninent script wrapper for a MBean of given ObjectName";

if (this.application != undefined) {
    this.application.addTool("JMX Connect",
        // connect to a JMX MBean Server
        function () {
            var url = prompt("Connect to JMX server (host:port)");
            if (url != null) {
                try {
                    jmxConnect(url);
                    alert("connected!");
                } catch (e) {
                    error(e, "Can not connect to " + url);
                }
            }
        });
}
