/*
 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.management;

import java.lang.management.ManagementFactory;
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 javax.management.ObjectName;

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");
        }

        Util.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() {
        Util.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");
        }

        Util.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 AssertionError("Should not reach here");
        }
        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 AssertionError("Should not reach here");
        }
        void clearAction() {
            // do nothing
        }
    }

    public ObjectName getObjectName() {
        return Util.newObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE, getName());
    }

}
