/*
 * Copyright 2003-2005 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;

import java.lang.management.MemoryPoolMXBean;

import java.lang.management.MemoryUsage;
import java.lang.management.MemoryType;
import java.lang.management.MemoryManagerMXBean;
import javax.management.openmbean.CompositeData;

import static java.lang.management.MemoryNotificationInfo.*;

/**
 * Implementation class for a memory pool.
 * Standard and committed hotspot-specific metrics if any.
 *
 * ManagementFactory.getMemoryPoolMXBeans() returns a list of
 * instances of this class.
 */
class MemoryPoolImpl implements MemoryPoolMXBean {

    private final String  name;
    private final boolean isHeap;
    private final boolean isValid;
    private final boolean collectionThresholdSupported;
    private final boolean usageThresholdSupported;

    private MemoryManagerMXBean[] managers;

    private long  usageThreshold;
    private long  collectionThreshold;

    private boolean usageSensorRegistered;
    private boolean gcSensorRegistered;
    private Sensor  usageSensor;
    private Sensor  gcSensor;

    MemoryPoolImpl(String name, boolean isHeap, long usageThreshold,
                   long gcThreshold) {
        this.name = name;
        this.isHeap = isHeap;
        this.isValid = true;
        this.managers = null;
        this.usageThreshold = usageThreshold;
        this.collectionThreshold = gcThreshold;
        this.usageThresholdSupported = (usageThreshold >= 0);
        this.collectionThresholdSupported = (gcThreshold >= 0);
        this.usageSensor = new PoolSensor(this, name + " usage sensor");
        this.gcSensor = new CollectionSensor(this, name + " collection sensor");
        this.usageSensorRegistered = false;
        this.gcSensorRegistered = false;
    }

    public String getName() {
        return name;
    }

    public boolean isValid() {
        return isValid;
    }

    public MemoryType getType() {
        if (isHeap) {
            return MemoryType.HEAP;
        } else {
            return MemoryType.NON_HEAP;
        }
    }

    public MemoryUsage getUsage() {
        return getUsage0();
    }

    public synchronized MemoryUsage getPeakUsage() {
        // synchronized since resetPeakUsage may be resetting the peak usage
        return getPeakUsage0();
    }

    public synchronized long getUsageThreshold() {
        if (!isUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "Usage threshold is not supported");
        }
        return usageThreshold;
    }

    public void setUsageThreshold(long newThreshold) {
        if (!isUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "Usage threshold is not supported");
        }

        ManagementFactory.checkControlAccess();

        MemoryUsage usage = getUsage0();
        if (newThreshold < 0) {
            throw new IllegalArgumentException(
                "Invalid threshold: " + newThreshold);
        }

        if (usage.getMax() != -1 && newThreshold > usage.getMax()) {
            throw new IllegalArgumentException(
                "Invalid threshold: " + newThreshold +
                " must be <= maxSize." +
                " Committed = " + usage.getCommitted() +
                " Max = " + usage.getMax());
        }

        synchronized (this) {
            if (!usageSensorRegistered) {
                // pass the sensor to VM to begin monitoring
                usageSensorRegistered = true;
                setPoolUsageSensor(usageSensor);
            }
            setUsageThreshold0(usageThreshold, newThreshold);
            this.usageThreshold = newThreshold;
        }
    }

    private synchronized MemoryManagerMXBean[] getMemoryManagers() {
        if (managers == null) {
            managers = getMemoryManagers0();
        }
        return managers;
    }

    public String[] getMemoryManagerNames() {
        MemoryManagerMXBean[] mgrs = getMemoryManagers();

        String[] names = new String[mgrs.length];
        for (int i = 0; i < mgrs.length; i++) {
            names[i] = mgrs[i].getName();
        }
        return names;
    }

    public void resetPeakUsage() {
        ManagementFactory.checkControlAccess();

        synchronized (this) {
            // synchronized since getPeakUsage may be called concurrently
            resetPeakUsage0();
        }
    }

    public boolean isUsageThresholdExceeded() {
        if (!isUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "Usage threshold is not supported");
        }

        // return false if usage threshold crossing checking is disabled
        if (usageThreshold == 0) {
            return false;
        }

        MemoryUsage u = getUsage0();
        return (u.getUsed() >= usageThreshold ||
                usageSensor.isOn());
    }

    public long getUsageThresholdCount() {
        if (!isUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "Usage threshold is not supported");
        }

        return usageSensor.getCount();
    }

    public boolean isUsageThresholdSupported() {
        return usageThresholdSupported;
    }

    public synchronized long getCollectionUsageThreshold() {
        if (!isCollectionUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "CollectionUsage threshold is not supported");
        }

        return collectionThreshold;
    }

    public void setCollectionUsageThreshold(long newThreshold) {
        if (!isCollectionUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "CollectionUsage threshold is not supported");
        }

        ManagementFactory.checkControlAccess();

        MemoryUsage usage = getUsage0();
        if (newThreshold < 0) {
            throw new IllegalArgumentException(
                "Invalid threshold: " + newThreshold);
        }

        if (usage.getMax() != -1 && newThreshold > usage.getMax()) {
            throw new IllegalArgumentException(
                "Invalid threshold: " + newThreshold +
                     " > max (" + usage.getMax() + ").");
        }

        synchronized (this) {
            if (!gcSensorRegistered) {
                // pass the sensor to VM to begin monitoring
                gcSensorRegistered = true;
                setPoolCollectionSensor(gcSensor);
            }
            setCollectionThreshold0(collectionThreshold, newThreshold);
            this.collectionThreshold = newThreshold;
        }
    }

    public boolean isCollectionUsageThresholdExceeded() {
        if (!isCollectionUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "CollectionUsage threshold is not supported");
        }

        // return false if usage threshold crossing checking is disabled
        if (collectionThreshold == 0) {
            return false;
        }

        MemoryUsage u = getCollectionUsage0();
        return (gcSensor.isOn() ||
                (u != null && u.getUsed() >= collectionThreshold));
    }

    public long getCollectionUsageThresholdCount() {
        if (!isCollectionUsageThresholdSupported()) {
            throw new UnsupportedOperationException(
                "CollectionUsage threshold is not supported");
        }

        return gcSensor.getCount();
    }

    public MemoryUsage getCollectionUsage() {
        return getCollectionUsage0();
    }

    public boolean isCollectionUsageThresholdSupported() {
        return collectionThresholdSupported;
    }

    // Native VM support
    private native MemoryUsage getUsage0();
    private native MemoryUsage getPeakUsage0();
    private native MemoryUsage getCollectionUsage0();
    private native void setUsageThreshold0(long current, long newThreshold);
    private native void setCollectionThreshold0(long current, long newThreshold);
    private native void resetPeakUsage0();
    private native MemoryManagerMXBean[] getMemoryManagers0();
    private native void setPoolUsageSensor(Sensor s);
    private native void setPoolCollectionSensor(Sensor s);

    // package private

    /**
     * PoolSensor will be triggered by the VM when the memory
     * usage of a memory pool is crossing the usage threshold.
     * The VM will not trigger this sensor in subsequent crossing
     * unless the memory usage has returned below the threshold.
     */
    class PoolSensor extends Sensor {
        MemoryPoolImpl pool;

        PoolSensor(MemoryPoolImpl pool, String name) {
            super(name);
            this.pool = pool;
        }
        void triggerAction(MemoryUsage usage) {
            // create and send notification
            MemoryImpl.createNotification(MEMORY_THRESHOLD_EXCEEDED,
                                          pool.getName(),
                                          usage,
                                          getCount());
        }
        void triggerAction() {
            // Should not reach here
            throw new InternalError();
        }
        void clearAction() {
            // do nothing
        }
    }

    /**
     * CollectionSensor will be triggered and cleared by the VM
     * when the memory usage of a memory pool after GC is crossing
     * the collection threshold.
     * The VM will trigger this sensor in subsequent crossing
     * regardless if the memory usage has changed siince the previous GC.
     */
    class CollectionSensor extends Sensor {
        MemoryPoolImpl pool;
        CollectionSensor(MemoryPoolImpl pool, String name) {
            super(name);
            this.pool = pool;
        }
        void triggerAction(MemoryUsage usage) {
            MemoryImpl.createNotification(MEMORY_COLLECTION_THRESHOLD_EXCEEDED,
                                          pool.getName(),
                                          usage,
                                          gcSensor.getCount());
        }
        void triggerAction() {
            // Should not reach here
            throw new InternalError();
        }
        void clearAction() {
            // do nothing
        }
    }
}
