/*
 * Copyright (c) 2003, 2004, 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.snmp.jvminstr;

// java imports
//
import java.io.Serializable;
import java.lang.management.ThreadInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

// jmx imports
//
import com.sun.jmx.snmp.SnmpStatusException;

// jdmk imports
//
import com.sun.jmx.snmp.agent.SnmpMib;
import com.sun.jmx.snmp.SnmpOid;
import com.sun.jmx.snmp.SnmpDefinitions;
import com.sun.jmx.snmp.SnmpOidTable;
import com.sun.jmx.snmp.SnmpOidRecord;

import sun.management.snmp.jvmmib.JvmThreadInstanceEntryMBean;
import sun.management.snmp.jvmmib.JVM_MANAGEMENT_MIBOidTable;
import sun.management.snmp.util.MibLogger;

/**
 * The class is used for implementing the "JvmThreadInstanceEntry" group.
 */
public class JvmThreadInstanceEntryImpl
    implements JvmThreadInstanceEntryMBean, Serializable {

    public final static class ThreadStateMap {
        public final static class Byte0 {
            public final static byte inNative     = (byte)0x80; // bit 1
            public final static byte suspended    = (byte)0x40; // bit 2
            public final static byte newThread    = (byte)0x20; // bit 3
            public final static byte runnable     = (byte)0x10; // bit 4
            public final static byte blocked      = (byte)0x08; // bit 5
            public final static byte terminated   = (byte)0x04; // bit 6
            public final static byte waiting      = (byte)0x02; // bit 7
            public final static byte timedWaiting = (byte)0x01; // bit 8
        }
        public final static class Byte1 {
            public final static byte other        = (byte)0x80; // bit 9
            public final static byte reserved10   = (byte)0x40; // bit 10
            public final static byte reserved11   = (byte)0x20; // bit 11
            public final static byte reserved12   = (byte)0x10; // bit 12
            public final static byte reserved13   = (byte)0x08; // bit 13
            public final static byte reserved14   = (byte)0x04; // bit 14
            public final static byte reserved15   = (byte)0x02; // bit 15
            public final static byte reserved16   = (byte)0x01; // bit 16
        }

        public final static byte mask0 = (byte)0x3F;
        public final static byte mask1 = (byte)0x80;

        private static void setBit(byte[] bitmap, int index, byte state) {
            bitmap[index] = (byte) (bitmap[index] | state);
        }
        public static void setNative(byte[] bitmap) {
            setBit(bitmap,0,Byte0.inNative);
        }
        public static void setSuspended(byte[] bitmap) {
            setBit(bitmap,0,Byte0.suspended);
        }
        public static void setState(byte[] bitmap, Thread.State state) {
            switch(state) {
            case BLOCKED:
                setBit(bitmap,0,Byte0.blocked);
                return;
            case NEW:
                setBit(bitmap,0,Byte0.newThread);
                return;
            case RUNNABLE:
                setBit(bitmap,0,Byte0.runnable);
                return;
            case TERMINATED:
                setBit(bitmap,0,Byte0.terminated);
                return;
            case TIMED_WAITING:
                setBit(bitmap,0,Byte0.timedWaiting);
                return;
            case WAITING:
                setBit(bitmap,0,Byte0.waiting);
                return;
            }
        }

        public static void checkOther(byte[] bitmap) {
            if (((bitmap[0]&mask0)==(byte)0x00) &&
                ((bitmap[1]&mask1)==(byte)0x00))
                setBit(bitmap,1,Byte1.other);
        }

        public static Byte[] getState(ThreadInfo info) {
            byte[] bitmap = new byte[] {(byte)0x00, (byte)0x00};
            try {
                final Thread.State state = info.getThreadState();
                final boolean inNative  = info.isInNative();
                final boolean suspended = info.isSuspended();
                log.debug("getJvmThreadInstState",
                          "[State=" + state +
                          ",isInNative=" + inNative +
                          ",isSuspended=" + suspended + "]");
                setState(bitmap,state);
                if (inNative)  setNative(bitmap);
                if (suspended) setSuspended(bitmap);
                checkOther(bitmap);
            } catch (RuntimeException r) {
                bitmap[0]=(byte)0x00;
                bitmap[1]=Byte1.other;
                log.trace("getJvmThreadInstState",
                          "Unexpected exception: " + r);
                log.debug("getJvmThreadInstState",r);
            }
            Byte[] result = { new Byte(bitmap[0]), new Byte(bitmap[1]) };
            return result;
        }
    }

    private final ThreadInfo info;
    private final Byte[] index;

    /**
     * Constructor for the "JvmThreadInstanceEntry" group.
     */
    public JvmThreadInstanceEntryImpl(ThreadInfo info,
                                      Byte[] index) {
        this.info = info;
        this.index = index;
    }


    private static String  jvmThreadInstIndexOid = null;
    public static String getJvmThreadInstIndexOid()
        throws SnmpStatusException {
        if (jvmThreadInstIndexOid == null) {
            final SnmpOidTable  table = new JVM_MANAGEMENT_MIBOidTable();
            final SnmpOidRecord record =
                table.resolveVarName("jvmThreadInstIndex");
            jvmThreadInstIndexOid = record.getOid();
        }
        return jvmThreadInstIndexOid;
    }



    /**
     * Getter for the "JvmThreadInstLockedOwnerId" variable.
     */
    public String getJvmThreadInstLockOwnerPtr() throws SnmpStatusException {
       long id = info.getLockOwnerId();

       if(id == -1)
           return new String("0.0");

       SnmpOid oid = JvmThreadInstanceTableMetaImpl.makeOid(id);

       return getJvmThreadInstIndexOid() + "." + oid.toString();
    }

    private String validDisplayStringTC(String str) {
        return JVM_MANAGEMENT_MIB_IMPL.validDisplayStringTC(str);
    }

    private String validJavaObjectNameTC(String str) {
        return JVM_MANAGEMENT_MIB_IMPL.validJavaObjectNameTC(str);
    }

    private String validPathElementTC(String str) {
        return JVM_MANAGEMENT_MIB_IMPL.validPathElementTC(str);
    }

    /**
     * Getter for the "JvmThreadInstLockName" variable.
     */
    public String getJvmThreadInstLockName() throws SnmpStatusException {
        return validJavaObjectNameTC(info.getLockName());
    }

    /**
     * Getter for the "JvmThreadInstName" variable.
     */
    public String getJvmThreadInstName() throws SnmpStatusException {
        return validJavaObjectNameTC(info.getThreadName());
    }

    /**
     * Getter for the "JvmThreadInstCpuTimeNs" variable.
     */
    public Long getJvmThreadInstCpuTimeNs() throws SnmpStatusException {
        long l = 0;
        final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean();

        try {
            if (tmb.isThreadCpuTimeSupported()) {
                l = tmb.getThreadCpuTime(info.getThreadId());
                log.debug("getJvmThreadInstCpuTimeNs", "Cpu time ns : " + l);

                //Cpu time measurement is disabled or the id is not valid.
                if(l == -1) l = 0;
            }
        } catch (UnsatisfiedLinkError e) {
            // XXX Revisit: catch TO BE EVENTUALLY REMOVED
            log.debug("getJvmThreadInstCpuTimeNs",
                      "Operation not supported: " + e);
        }
        return new Long(l);
    }

    /**
     * Getter for the "JvmThreadInstBlockTimeMs" variable.
     */
    public Long getJvmThreadInstBlockTimeMs() throws SnmpStatusException {
        long l = 0;

        final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean();

        if (tmb.isThreadContentionMonitoringSupported()) {
            l = info.getBlockedTime();

            //Monitoring is disabled
            if(l == -1) l = 0;
        }
        return new Long(l);
    }

    /**
     * Getter for the "JvmThreadInstBlockCount" variable.
     */
    public Long getJvmThreadInstBlockCount() throws SnmpStatusException {
        return new Long(info.getBlockedCount());
    }

    /**
     * Getter for the "JvmThreadInstWaitTimeMs" variable.
     */
    public Long getJvmThreadInstWaitTimeMs() throws SnmpStatusException {
        long l = 0;

        final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean();

        if (tmb.isThreadContentionMonitoringSupported()) {
            l = info.getWaitedTime();

            //Monitoring is disabled
            if(l == -1) l = 0;
        }
        return new Long(l);
    }

    /**
     * Getter for the "JvmThreadInstWaitCount" variable.
     */
    public Long getJvmThreadInstWaitCount() throws SnmpStatusException {
        return new Long(info.getWaitedCount());
    }

    /**
     * Getter for the "JvmThreadInstState" variable.
     */
    public Byte[] getJvmThreadInstState()
        throws SnmpStatusException {
        return ThreadStateMap.getState(info);
    }

    /**
     * Getter for the "JvmThreadInstId" variable.
     */
    public Long getJvmThreadInstId() throws SnmpStatusException {
        return new Long(info.getThreadId());
    }

    /**
     * Getter for the "JvmThreadInstIndex" variable.
     */
    public Byte[] getJvmThreadInstIndex() throws SnmpStatusException {
        return index;
    }

    /**
     * Getter for the "JvmThreadInstStackTrace" variable.
     */
    private String getJvmThreadInstStackTrace() throws SnmpStatusException {
        StackTraceElement[] stackTrace = info.getStackTrace();
        //We append the stack trace in a buffer
        // XXX Revisit: should check isDebugOn()
        StringBuffer b = new StringBuffer();
        final int stackSize = stackTrace.length;
        log.debug("getJvmThreadInstStackTrace", "Stack size : " + stackSize);
        for(int i = 0; i < stackSize; i++) {
            log.debug("getJvmThreadInstStackTrace", "Append " +
                      stackTrace[i].toString());
            b.append(stackTrace[i].toString());
            //Append \n at the end of each line except the last one
            if(i < stackSize)
                b.append("\n");
        }
        //The stack trace is truncated if its size exceeds 255.
        return validPathElementTC(b.toString());
    }
    static final MibLogger log =
        new MibLogger(JvmThreadInstanceEntryImpl.class);
}
