/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.catalina.manager;


import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import javax.management.MBeanServer;
import javax.management.MBeanServerNotification;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.util.ServerInfo;
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomcat.util.res.StringManager;

/**
 * This servlet will display a complete status of the HTTP/1.1 connector.
 *
 * @author Remy Maucherat
 */
public class StatusManagerServlet
    extends HttpServlet implements NotificationListener {

    private static final long serialVersionUID = 1L;

    // ----------------------------------------------------- Instance Variables
    /**
     * MBean server.
     */
    protected MBeanServer mBeanServer = null;


    /**
     * Vector of protocol handlers object names.
     */
    protected final Vector<ObjectName> protocolHandlers = new Vector<>();


    /**
     * Vector of thread pools object names.
     */
    protected final Vector<ObjectName> threadPools = new Vector<>();


    /**
     * Vector of request processors object names.
     */
    protected final Vector<ObjectName> requestProcessors = new Vector<>();


    /**
     * Vector of global request processors object names.
     */
    protected final Vector<ObjectName> globalRequestProcessors = new Vector<>();


    /**
     * The string manager for this package.
     */
    protected static final StringManager sm =
        StringManager.getManager(Constants.Package);


    // --------------------------------------------------------- Public Methods


    /**
     * Initialize this servlet.
     */
    @Override
    public void init() throws ServletException {

        // Retrieve the MBean server
        mBeanServer = Registry.getRegistry(null, null).getMBeanServer();

        try {

            // Query protocol handlers
            String onStr = "*:type=ProtocolHandler,*";
            ObjectName objectName = new ObjectName(onStr);
            Set<ObjectInstance> set = mBeanServer.queryMBeans(objectName, null);
            Iterator<ObjectInstance> iterator = set.iterator();
            while (iterator.hasNext()) {
                ObjectInstance oi = iterator.next();
                protocolHandlers.addElement(oi.getObjectName());
            }

            // Query Thread Pools
            onStr = "*:type=ThreadPool,*";
            objectName = new ObjectName(onStr);
            set = mBeanServer.queryMBeans(objectName, null);
            onStr = "*:type=ThreadPool,*,subType=SocketProperties";
            objectName = new ObjectName(onStr);
            Set<ObjectInstance> set2 = mBeanServer.queryMBeans(objectName, null);
            iterator = set.iterator();
            while (iterator.hasNext()) {
                ObjectInstance oi = iterator.next();
                if (!set2.contains(oi)) {
                    threadPools.addElement(oi.getObjectName());
                }
            }

            // Query Global Request Processors
            onStr = "*:type=GlobalRequestProcessor,*";
            objectName = new ObjectName(onStr);
            set = mBeanServer.queryMBeans(objectName, null);
            iterator = set.iterator();
            while (iterator.hasNext()) {
                ObjectInstance oi = iterator.next();
                globalRequestProcessors.addElement(oi.getObjectName());
            }

            // Query Request Processors
            onStr = "*:type=RequestProcessor,*";
            objectName = new ObjectName(onStr);
            set = mBeanServer.queryMBeans(objectName, null);
            iterator = set.iterator();
            while (iterator.hasNext()) {
                ObjectInstance oi = iterator.next();
                requestProcessors.addElement(oi.getObjectName());
            }

            // Register with MBean server
            onStr = "JMImplementation:type=MBeanServerDelegate";
            objectName = new ObjectName(onStr);
            mBeanServer.addNotificationListener(objectName, this, null, null);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * Finalize this servlet.
     */
    @Override
    public void destroy() {

        // Unregister with MBean server
        String onStr = "JMImplementation:type=MBeanServerDelegate";
        ObjectName objectName;
        try {
            objectName = new ObjectName(onStr);
            mBeanServer.removeNotificationListener(objectName, this, null, null);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * Process a GET request for the specified resource.
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet-specified error occurs
     */
    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException {

        StringManager smClient = StringManager.getManager(
                Constants.Package, request.getLocales());

        // mode is flag for HTML or XML output
        int mode = 0;
        // if ?XML=true, set the mode to XML
        if (request.getParameter("XML") != null
            && request.getParameter("XML").equals("true")) {
            mode = 1;
        }
        StatusTransformer.setContentType(response, mode);

        PrintWriter writer = response.getWriter();

        boolean completeStatus = false;
        if ((request.getPathInfo() != null)
            && (request.getPathInfo().equals("/all"))) {
            completeStatus = true;
        }
        // use StatusTransformer to output status
        Object[] args = new Object[1];
        args[0] = request.getContextPath();
        StatusTransformer.writeHeader(writer,args,mode);

        // Body Header Section
        args = new Object[2];
        args[0] = request.getContextPath();
        if (completeStatus) {
            args[1] = smClient.getString("statusServlet.complete");
        } else {
            args[1] = smClient.getString("statusServlet.title");
        }
        // use StatusTransformer to output status
        StatusTransformer.writeBody(writer,args,mode);

        // Manager Section
        args = new Object[9];
        args[0] = smClient.getString("htmlManagerServlet.manager");
        args[1] = response.encodeURL(request.getContextPath() + "/html/list");
        args[2] = smClient.getString("htmlManagerServlet.list");
        args[3] = // External link
            (request.getContextPath() + "/" +
             smClient.getString("htmlManagerServlet.helpHtmlManagerFile"));
        args[4] = smClient.getString("htmlManagerServlet.helpHtmlManager");
        args[5] = // External link
            (request.getContextPath() + "/" +
             smClient.getString("htmlManagerServlet.helpManagerFile"));
        args[6] = smClient.getString("htmlManagerServlet.helpManager");
        if (completeStatus) {
            args[7] = response.encodeURL
                (request.getContextPath() + "/status");
            args[8] = smClient.getString("statusServlet.title");
        } else {
            args[7] = response.encodeURL
                (request.getContextPath() + "/status/all");
            args[8] = smClient.getString("statusServlet.complete");
        }
        // use StatusTransformer to output status
        StatusTransformer.writeManager(writer,args,mode);

        // Server Header Section
        args = new Object[9];
        args[0] = smClient.getString("htmlManagerServlet.serverTitle");
        args[1] = smClient.getString("htmlManagerServlet.serverVersion");
        args[2] = smClient.getString("htmlManagerServlet.serverJVMVersion");
        args[3] = smClient.getString("htmlManagerServlet.serverJVMVendor");
        args[4] = smClient.getString("htmlManagerServlet.serverOSName");
        args[5] = smClient.getString("htmlManagerServlet.serverOSVersion");
        args[6] = smClient.getString("htmlManagerServlet.serverOSArch");
        args[7] = smClient.getString("htmlManagerServlet.serverHostname");
        args[8] = smClient.getString("htmlManagerServlet.serverIPAddress");
        // use StatusTransformer to output status
        StatusTransformer.writePageHeading(writer,args,mode);

        // Server Row Section
        args = new Object[8];
        args[0] = ServerInfo.getServerInfo();
        args[1] = System.getProperty("java.runtime.version");
        args[2] = System.getProperty("java.vm.vendor");
        args[3] = System.getProperty("os.name");
        args[4] = System.getProperty("os.version");
        args[5] = System.getProperty("os.arch");
        try {
            InetAddress address = InetAddress.getLocalHost();
            args[6] = address.getHostName();
            args[7] = address.getHostAddress();
         } catch (UnknownHostException e) {
            args[6] = "-";
            args[7] = "-";
        }
        // use StatusTransformer to output status
        StatusTransformer.writeServerInfo(writer, args, mode);

        try {

            // Display operating system statistics using APR if available
            args = new Object[7];
            args[0] = smClient.getString("htmlManagerServlet.osPhysicalMemory");
            args[1] = smClient.getString("htmlManagerServlet.osAvailableMemory");
            args[2] = smClient.getString("htmlManagerServlet.osTotalPageFile");
            args[3] = smClient.getString("htmlManagerServlet.osFreePageFile");
            args[4] = smClient.getString("htmlManagerServlet.osMemoryLoad");
            args[5] = smClient.getString("htmlManagerServlet.osKernelTime");
            args[6] = smClient.getString("htmlManagerServlet.osUserTime");
            StatusTransformer.writeOSState(writer, mode, args);

            // Display virtual machine statistics
            args = new Object[9];
            args[0] = smClient.getString("htmlManagerServlet.jvmFreeMemory");
            args[1] = smClient.getString("htmlManagerServlet.jvmTotalMemory");
            args[2] = smClient.getString("htmlManagerServlet.jvmMaxMemory");
            args[3] = smClient.getString("htmlManagerServlet.jvmTableTitleMemoryPool");
            args[4] = smClient.getString("htmlManagerServlet.jvmTableTitleType");
            args[5] = smClient.getString("htmlManagerServlet.jvmTableTitleInitial");
            args[6] = smClient.getString("htmlManagerServlet.jvmTableTitleTotal");
            args[7] = smClient.getString("htmlManagerServlet.jvmTableTitleMaximum");
            args[8] = smClient.getString("htmlManagerServlet.jvmTableTitleUsed");
            // use StatusTransformer to output status
            StatusTransformer.writeVMState(writer,mode, args);

            Enumeration<ObjectName> enumeration = threadPools.elements();
            while (enumeration.hasMoreElements()) {
                ObjectName objectName = enumeration.nextElement();
                String name = objectName.getKeyProperty("name");
                args = new Object[19];
                args[0] = smClient.getString("htmlManagerServlet.connectorStateMaxThreads");
                args[1] = smClient.getString("htmlManagerServlet.connectorStateThreadCount");
                args[2] = smClient.getString("htmlManagerServlet.connectorStateThreadBusy");
                args[3] = smClient.getString("htmlManagerServlet.connectorStateAliveSocketCount");
                args[4] = smClient.getString("htmlManagerServlet.connectorStateMaxProcessingTime");
                args[5] = smClient.getString("htmlManagerServlet.connectorStateProcessingTime");
                args[6] = smClient.getString("htmlManagerServlet.connectorStateRequestCount");
                args[7] = smClient.getString("htmlManagerServlet.connectorStateErrorCount");
                args[8] = smClient.getString("htmlManagerServlet.connectorStateBytesRecieved");
                args[9] = smClient.getString("htmlManagerServlet.connectorStateBytesSent");
                args[10] = smClient.getString("htmlManagerServlet.connectorStateTableTitleStage");
                args[11] = smClient.getString("htmlManagerServlet.connectorStateTableTitleTime");
                args[12] = smClient.getString("htmlManagerServlet.connectorStateTableTitleBSent");
                args[13] = smClient.getString("htmlManagerServlet.connectorStateTableTitleBRecv");
                args[14] = smClient.getString("htmlManagerServlet.connectorStateTableTitleClientForw");
                args[15] = smClient.getString("htmlManagerServlet.connectorStateTableTitleClientAct");
                args[16] = smClient.getString("htmlManagerServlet.connectorStateTableTitleVHost");
                args[17] = smClient.getString("htmlManagerServlet.connectorStateTableTitleRequest");
                args[18] = smClient.getString("htmlManagerServlet.connectorStateHint");
                // use StatusTransformer to output status
                StatusTransformer.writeConnectorState
                    (writer, objectName,
                     name, mBeanServer, globalRequestProcessors,
                     requestProcessors, mode, args);
            }

            if ((request.getPathInfo() != null)
                && (request.getPathInfo().equals("/all"))) {
                // Note: Retrieving the full status is much slower
                // use StatusTransformer to output status
                StatusTransformer.writeDetailedState
                    (writer, mBeanServer, mode);
            }

        } catch (Exception e) {
            throw new ServletException(e);
        }

        // use StatusTransformer to output status
        StatusTransformer.writeFooter(writer, mode);

    }

    // ------------------------------------------- NotificationListener Methods


    @Override
    public void handleNotification(Notification notification,
                                   java.lang.Object handback) {

        if (notification instanceof MBeanServerNotification) {
            ObjectName objectName =
                ((MBeanServerNotification) notification).getMBeanName();
            if (notification.getType().equals
                (MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
                String type = objectName.getKeyProperty("type");
                if (type != null) {
                    if (type.equals("ProtocolHandler")) {
                        protocolHandlers.addElement(objectName);
                    } else if (type.equals("ThreadPool")) {
                        threadPools.addElement(objectName);
                    } else if (type.equals("GlobalRequestProcessor")) {
                        globalRequestProcessors.addElement(objectName);
                    } else if (type.equals("RequestProcessor")) {
                        requestProcessors.addElement(objectName);
                    }
                }
            } else if (notification.getType().equals
                       (MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
                String type = objectName.getKeyProperty("type");
                if (type != null) {
                    if (type.equals("ProtocolHandler")) {
                        protocolHandlers.removeElement(objectName);
                    } else if (type.equals("ThreadPool")) {
                        threadPools.removeElement(objectName);
                    } else if (type.equals("GlobalRequestProcessor")) {
                        globalRequestProcessors.removeElement(objectName);
                    } else if (type.equals("RequestProcessor")) {
                        requestProcessors.removeElement(objectName);
                    }
                }
            }
        }
    }
}
