/*
 * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package sun.management.snmp.jvminstr;

// jmx imports
//
import javax.management.MBeanServer;
import com.sun.jmx.snmp.SnmpStatusException;
import com.sun.jmx.snmp.SnmpDefinitions;

// jdmk imports
//
import com.sun.jmx.snmp.agent.SnmpMib;

import java.util.Map;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.MemoryType;
import java.lang.management.MemoryMXBean;
import javax.management.openmbean.CompositeData;

import sun.management.snmp.jvmmib.JvmMemoryMBean;
import sun.management.snmp.jvmmib.EnumJvmMemoryGCCall;
import sun.management.snmp.jvmmib.EnumJvmMemoryGCVerboseLevel;
import sun.management.snmp.util.MibLogger;
import sun.management.snmp.util.JvmContextFactory;

/**
 * The class is used for implementing the "JvmMemory" group.
 */
public class JvmMemoryImpl implements JvmMemoryMBean {

    /**
     * Variable for storing the value of "JvmMemoryGCCall".
     *
     * "This object makes it possible to remotelly trigger the
     * Garbage Collector in the JVM.
     *
     * This object's syntax is an enumeration which defines:
     *
     * * Two state values, that can be returned from a GET request:
     *
     * unsupported(1): means that remote invocation of gc() is not
     * supported by the SNMP agent.
     * supported(2)  : means that remote invocation of gc() is supported
     * by the SNMP agent.
     *
     * * One action value, that can be provided in a SET request to
     * trigger the garbage collector:
     *
     * start(3)      : means that a manager wishes to trigger
     * garbage collection.
     *
     * * Two result value, that will be returned as a result of a
     * SET request when remote invocation of gc is supported
     * by the SNMP agent:
     *
     * started(4)       : means that garbage collection was
     * successfully triggered. It does not mean
     * however that the action was successfullly
     * completed: gc might still be running when
     * this value is returned.
     * failed(5)     : means that garbage collection couldn't be
     * triggered.
     *
     * * If remote invocation is not supported by the SNMP agent, then
     * unsupported(1) will always be returned as a result of either
     * a GET request, or a SET request with start(3) as input value.
     *
     * * If a SET request with anything but start(3) is received, then
     * the agent will return a wrongValue error.
     *
     * See java.management.MemoryMXBean.gc()
     * "
     *
     */
    final static EnumJvmMemoryGCCall JvmMemoryGCCallSupported
        = new EnumJvmMemoryGCCall("supported");
    final static EnumJvmMemoryGCCall JvmMemoryGCCallStart
        = new EnumJvmMemoryGCCall("start");
    final static EnumJvmMemoryGCCall JvmMemoryGCCallFailed
        = new EnumJvmMemoryGCCall("failed");
    final static EnumJvmMemoryGCCall JvmMemoryGCCallStarted
        = new EnumJvmMemoryGCCall("started");

    /**
     * Variable for storing the value of "JvmMemoryGCVerboseLevel".
     *
     * "State of the -verbose:gc state.
     *
     * verbose: if the -verbose:gc flag is on,
     * silent:  otherwise.
     *
     * See java.management.MemoryMXBean.isVerbose(),
     * java.management.MemoryMXBean.setVerbose()
     * "
     *
     */
    final static EnumJvmMemoryGCVerboseLevel JvmMemoryGCVerboseLevelVerbose =
        new EnumJvmMemoryGCVerboseLevel("verbose");
    final static EnumJvmMemoryGCVerboseLevel JvmMemoryGCVerboseLevelSilent =
        new EnumJvmMemoryGCVerboseLevel("silent");

    /**
     * Constructor for the "JvmMemory" group.
     * If the group contains a table, the entries created through an
     * SNMP SET will not be registered in Java DMK.
     */
    public JvmMemoryImpl(SnmpMib myMib) {
    }


    /**
     * Constructor for the "JvmMemory" group.
     * If the group contains a table, the entries created through an
     * SNMP SET will be AUTOMATICALLY REGISTERED in Java DMK.
     */
    public JvmMemoryImpl(SnmpMib myMib, MBeanServer server) {
        // no entry will be registered since the table is virtual.
    }

    final static String heapMemoryTag = "jvmMemory.getHeapMemoryUsage";
    final static String nonHeapMemoryTag = "jvmMemory.getNonHeapMemoryUsage";

    private MemoryUsage getMemoryUsage(MemoryType type) {
        if (type == MemoryType.HEAP) {
            return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
        } else {
            return ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
        }
    }

    MemoryUsage getNonHeapMemoryUsage() {
        try {
            final Map<Object, Object> m = JvmContextFactory.getUserData();

            if (m != null) {
                final MemoryUsage cached = (MemoryUsage)
                    m.get(nonHeapMemoryTag);
                if (cached != null) {
                    log.debug("getNonHeapMemoryUsage",
                          "jvmMemory.getNonHeapMemoryUsage found in cache.");
                    return cached;
                }

                final MemoryUsage u = getMemoryUsage(MemoryType.NON_HEAP);

                //  getNonHeapMemoryUsage() never returns null.
                //
                // if (u == null) u=MemoryUsage.INVALID;

                m.put(nonHeapMemoryTag,u);
                return u;
            }
            // Should never come here.
            // Log error!
            log.trace("getNonHeapMemoryUsage",
                      "ERROR: should never come here!");
            return getMemoryUsage(MemoryType.NON_HEAP);
        } catch (RuntimeException x) {
            log.trace("getNonHeapMemoryUsage",
                  "Failed to get NonHeapMemoryUsage: " + x);
            log.debug("getNonHeapMemoryUsage",x);
            throw x;
        }

    }

    MemoryUsage getHeapMemoryUsage() {
        try {
            final Map<Object, Object> m = JvmContextFactory.getUserData();

            if (m != null) {
                final MemoryUsage cached = (MemoryUsage)m.get(heapMemoryTag);
                if (cached != null) {
                    log.debug("getHeapMemoryUsage",
                          "jvmMemory.getHeapMemoryUsage found in cache.");
                    return cached;
                }

                final MemoryUsage u = getMemoryUsage(MemoryType.HEAP);

                // getHeapMemoryUsage() never returns null.
                //
                // if (u == null) u=MemoryUsage.INVALID;

                m.put(heapMemoryTag,u);
                return u;
            }

            // Should never come here.
            // Log error!
            log.trace("getHeapMemoryUsage", "ERROR: should never come here!");
            return getMemoryUsage(MemoryType.HEAP);
        } catch (RuntimeException x) {
            log.trace("getHeapMemoryUsage",
                  "Failed to get HeapMemoryUsage: " + x);
            log.debug("getHeapMemoryUsage",x);
            throw x;
        }
    }

    static final Long Long0 = new Long(0);

    /**
     * Getter for the "JvmMemoryNonHeapMaxSize" variable.
     */
    public Long getJvmMemoryNonHeapMaxSize()
        throws SnmpStatusException {
        final long val = getNonHeapMemoryUsage().getMax();
        if (val > -1) return  new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryNonHeapCommitted" variable.
     */
    public Long getJvmMemoryNonHeapCommitted() throws SnmpStatusException {
        final long val = getNonHeapMemoryUsage().getCommitted();
        if (val > -1) return new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryNonHeapUsed" variable.
     */
    public Long getJvmMemoryNonHeapUsed() throws SnmpStatusException {
        final long val = getNonHeapMemoryUsage().getUsed();
        if (val > -1) return new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryNonHeapInitSize" variable.
     */
    public Long getJvmMemoryNonHeapInitSize() throws SnmpStatusException {
        final long val = getNonHeapMemoryUsage().getInit();
        if (val > -1) return new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryHeapMaxSize" variable.
     */
    public Long getJvmMemoryHeapMaxSize() throws SnmpStatusException {
        final long val = getHeapMemoryUsage().getMax();
        if (val > -1) return new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryGCCall" variable.
     */
    public EnumJvmMemoryGCCall getJvmMemoryGCCall()
        throws SnmpStatusException {
        final Map m = JvmContextFactory.getUserData();

        if (m != null) {
            final EnumJvmMemoryGCCall cached
                = (EnumJvmMemoryGCCall) m.get("jvmMemory.getJvmMemoryGCCall");
            if (cached != null) return cached;
        }
        return JvmMemoryGCCallSupported;
    }

    /**
     * Setter for the "JvmMemoryGCCall" variable.
     */
    public void setJvmMemoryGCCall(EnumJvmMemoryGCCall x)
        throws SnmpStatusException {
        if (x.intValue() == JvmMemoryGCCallStart.intValue()) {
            final Map<Object, Object> m = JvmContextFactory.getUserData();

            try {
                ManagementFactory.getMemoryMXBean().gc();
                if (m != null) m.put("jvmMemory.getJvmMemoryGCCall",
                                     JvmMemoryGCCallStarted);
            } catch (Exception ex) {
                if (m != null) m.put("jvmMemory.getJvmMemoryGCCall",
                                     JvmMemoryGCCallFailed);
            }
            return;
        }
        throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
    }

    /**
     * Checker for the "JvmMemoryGCCall" variable.
     */
    public void checkJvmMemoryGCCall(EnumJvmMemoryGCCall x)
        throws SnmpStatusException {
        if (x.intValue() != JvmMemoryGCCallStart.intValue())
        throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
    }

    /**
     * Getter for the "JvmMemoryHeapCommitted" variable.
     */
    public Long getJvmMemoryHeapCommitted() throws SnmpStatusException {
        final long val = getHeapMemoryUsage().getCommitted();
        if (val > -1) return new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryGCVerboseLevel" variable.
     */
    public EnumJvmMemoryGCVerboseLevel getJvmMemoryGCVerboseLevel()
        throws SnmpStatusException {
        if (ManagementFactory.getMemoryMXBean().isVerbose())
            return JvmMemoryGCVerboseLevelVerbose;
        else
            return JvmMemoryGCVerboseLevelSilent;
    }

    /**
     * Setter for the "JvmMemoryGCVerboseLevel" variable.
     */
    public void setJvmMemoryGCVerboseLevel(EnumJvmMemoryGCVerboseLevel x)
        throws SnmpStatusException {
        if (JvmMemoryGCVerboseLevelVerbose.intValue() == x.intValue())
            ManagementFactory.getMemoryMXBean().setVerbose(true);
        else
            ManagementFactory.getMemoryMXBean().setVerbose(false);
    }

    /**
     * Checker for the "JvmMemoryGCVerboseLevel" variable.
     */
    public void checkJvmMemoryGCVerboseLevel(EnumJvmMemoryGCVerboseLevel x)
        throws SnmpStatusException {
        // Nothing to check...
    }

    /**
     * Getter for the "JvmMemoryHeapUsed" variable.
     */
    public Long getJvmMemoryHeapUsed() throws SnmpStatusException {
        final long val = getHeapMemoryUsage().getUsed();
        if (val > -1) return new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryHeapInitSize" variable.
     */
    public Long getJvmMemoryHeapInitSize() throws SnmpStatusException {
        final long val = getHeapMemoryUsage().getInit();
        if (val > -1) return new Long(val);
        else return Long0;
    }

    /**
     * Getter for the "JvmMemoryPendingFinalCount" variable.
     */
    public Long getJvmMemoryPendingFinalCount()
        throws SnmpStatusException {
        final long val = ManagementFactory.getMemoryMXBean().
            getObjectPendingFinalizationCount();

        if (val > -1) return new Long((int)val);

        // Should never happen... but stay safe all the same.
        //
        else return new Long(0);
    }

    static final MibLogger log = new MibLogger(JvmMemoryImpl.class);
}
