/*
 * 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.cassandra.utils;

import java.io.*;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.text.StrBuilder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility to generate heap dumps.
 *
 */
public final class HeapUtils
{
    private static final Logger logger = LoggerFactory.getLogger(HeapUtils.class);

    /**
     * Generates a HEAP dump in the directory specified by the <code>HeapDumpPath</code> JVM option
     * or in the <code>CASSANDRA_HOME</code> directory.
     */
    public static void generateHeapDump()
    {
        Long processId = getProcessId();
        if (processId == null)
        {
            logger.error("The process ID could not be retrieved. Skipping heap dump generation.");
            return;
        }

        String heapDumpPath = getHeapDumpPathOption();
        if (heapDumpPath == null)
        {
            String cassandraHome = System.getenv("CASSANDRA_HOME");
            if (cassandraHome == null)
            {
                return;
            }

            heapDumpPath = cassandraHome;
        }

        Path dumpPath = FileSystems.getDefault().getPath(heapDumpPath);
        if (Files.isDirectory(dumpPath))
        {
            dumpPath = dumpPath.resolve("java_pid" + processId + ".hprof");
        }

        String jmapPath = getJmapPath();

        // The jmap file could not be found. In this case let's default to jmap in the hope that it is in the path.
        String jmapCommand = jmapPath == null ? "jmap" : jmapPath;

        String[] dumpCommands = new String[] {jmapCommand,
                                              "-dump:format=b,file=" + dumpPath,
                                              processId.toString()};

        // Lets also log the Heap histogram
        String[] histoCommands = new String[] {jmapCommand,
                                               "-histo",
                                               processId.toString()};
        try
        {
            logProcessOutput(Runtime.getRuntime().exec(dumpCommands));
            logProcessOutput(Runtime.getRuntime().exec(histoCommands));
        }
        catch (IOException e)
        {
            logger.error("The heap dump could not be generated due to the following error: ", e);
        }
    }

    /**
     * Retrieve the path to the JMAP executable.
     * @return the path to the JMAP executable or null if it cannot be found.
     */
    private static String getJmapPath()
    {
        // Searching in the JAVA_HOME is safer than searching into System.getProperty("java.home") as the Oracle
        // JVM might use the JRE which do not contains jmap.
        String javaHome = System.getenv("JAVA_HOME");
        if (javaHome == null)
            return null;

        File javaBinDirectory = new File(javaHome, "bin");
        File[] files = javaBinDirectory.listFiles(new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                return name.startsWith("jmap");
            }
        });
        return ArrayUtils.isEmpty(files) ? null : files[0].getPath();
    }

    /**
     * Logs the output of the specified process.
     *
     * @param p the process
     * @throws IOException if an I/O problem occurs
     */
    private static void logProcessOutput(Process p) throws IOException
    {
        BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));

        StrBuilder builder = new StrBuilder();
        String line;
        while ((line = input.readLine()) != null)
        {
            builder.appendln(line);
        }
        logger.info(builder.toString());
    }

    /**
     * Retrieves the value of the <code>HeapDumpPath</code> JVM option.
     * @return the value of the <code>HeapDumpPath</code> JVM option or <code>null</code> if the value has not been
     * specified.
     */
    private static String getHeapDumpPathOption()
    {
        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
        List<String> inputArguments = runtimeMxBean.getInputArguments();
        String heapDumpPathOption = null;
        for (String argument : inputArguments)
        {
            if (argument.startsWith("-XX:HeapDumpPath="))
            {
                heapDumpPathOption = argument;
                // We do not break in case the option has been specified several times.
                // In general it seems that JVMs use the right-most argument as the winner.
            }
        }

        if (heapDumpPathOption == null)
            return null;

        return heapDumpPathOption.substring(17, heapDumpPathOption.length());
    }

    /**
     * Retrieves the process ID or <code>null</code> if the process ID cannot be retrieved.
     * @return the process ID or <code>null</code> if the process ID cannot be retrieved.
     */
    private static Long getProcessId()
    {
        // Once Java 9 is ready the process API should provide a better way to get the process ID.
        long pid = SigarLibrary.instance.getPid();

        if (pid >= 0)
            return Long.valueOf(pid);

        return getProcessIdFromJvmName();
    }

    /**
     * Retrieves the process ID from the JVM name.
     * @return the process ID or <code>null</code> if the process ID cannot be retrieved.
     */
    private static Long getProcessIdFromJvmName()
    {
        // the JVM name in Oracle JVMs is: '<pid>@<hostname>' but this might not be the case on all JVMs
        String jvmName = ManagementFactory.getRuntimeMXBean().getName();
        try
        {
            return Long.parseLong(jvmName.split("@")[0]);
        }
        catch (NumberFormatException e)
        {
            // ignore
        }
        return null;
    }

    /**
     * The class must not be instantiated.
     */
    private HeapUtils()
    {
    }
}
