/*******************************************************************************
 * Copyright (c) 2003, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors: IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.test.internal.performance;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.StringTokenizer;

class PerformanceMonitorLinux extends PerformanceMonitor {

    private static long    PAGESIZE         = 4096;
    private static long    JIFFIES          = 10L;
    private static boolean fgHasElapsedTime = true;
    private static long    fgStartupTime;

    /**
     * Write out operating system counters for Linux.
     *
     * @param scalars
     */
    @Override
    protected void collectOperatingSystemCounters(Map scalars) {
        synchronized (this) {
            /**
             * The status values for a Linux process, that is the values that come from /proc/self/stat. The names of the variables match
             * the man proc page.
             */
            StringTokenizer st = readTokens("/proc/self/stat", false); //$NON-NLS-1$
            if (st != null) {
                st.nextToken(); // int pid; // Process id.
                st.nextToken(); // String comm; // The command name.
                st.nextToken(); // String state;
                st.nextToken(); // int ppid; // Parent process id. */
                st.nextToken(); // int pgrp; // Process group. */
                st.nextToken(); // int session;
                st.nextToken(); // int ttry_nr;
                st.nextToken(); // int tpgid;
                st.nextToken(); // long flags;
                long minflt = Long.parseLong(st.nextToken()); // Minor page faults (didn't need to load a page from disk). */
                st.nextToken(); // long cminflt; // Minor page faults for the process and it's children. */
                long majflt = Long.parseLong(st.nextToken()); // Major page faults. */
                st.nextToken(); // long cmajflt; // Major page faults for the process and it's children. */
                long utime = Long.parseLong(st.nextToken()); // User time in jiffies. */
                long stime = Long.parseLong(st.nextToken()); // System time in jiffies. */
                st.nextToken(); // long cutime; // User time for the process and it's children. */
                st.nextToken(); // long cstime; // System time for the process and it's children. */

                // addScalar(scalars, InternalDimensions.USER_TIME, utime*JIFFIES);
                addScalar(scalars, InternalDimensions.KERNEL_TIME, stime * JIFFIES);
                addScalar(scalars, InternalDimensions.CPU_TIME, (utime + stime) * JIFFIES);
                addScalar(scalars, InternalDimensions.SOFT_PAGE_FAULTS, minflt);
                addScalar(scalars, InternalDimensions.HARD_PAGE_FAULTS, majflt);
            }

            /**
             * The status memory values values for a Linux process, that is the values that come from /proc/self/statm. The names of the
             * variables match the man proc page.
             */
            st = readTokens("/proc/self/statm", false); //$NON-NLS-1$
            if (st != null) {
                st.nextToken(); // int size; // Size of the process in pages
                int resident = Integer.parseInt(st.nextToken()); // Resident size in pages.
                st.nextToken(); // int shared; // Shared size in pages.
                int trs = Integer.parseInt(st.nextToken()); // Text (code) size in pages.
                int drs = Integer.parseInt(st.nextToken()); // Data/Stack size in pages.
                int lrs = Integer.parseInt(st.nextToken()); // Library size in pages.
                // st.nextToken(); // int dt; // Dirty pages.

                addScalar(scalars, InternalDimensions.WORKING_SET, resident * PAGESIZE);
                addScalar(scalars, InternalDimensions.TRS, trs * PAGESIZE);
                addScalar(scalars, InternalDimensions.DRS, drs * PAGESIZE);
                addScalar(scalars, InternalDimensions.LRS, lrs * PAGESIZE);
            }

            long currentTime = System.currentTimeMillis();

            addScalar(scalars, InternalDimensions.SYSTEM_TIME, currentTime);

            if (fgHasElapsedTime) {
                if (fgStartupTime == 0) {
                    String t = System.getProperty("eclipse.startTime"); //$NON-NLS-1$
                    if (t != null) {
                        try {
                            fgStartupTime = Long.parseLong(t);
                        } catch (NumberFormatException e) {
                            fgHasElapsedTime = false;
                        }
                    } else
                        fgHasElapsedTime = false;
                }
                if (fgHasElapsedTime)
                    addScalar(scalars, InternalDimensions.ELAPSED_PROCESS, currentTime - fgStartupTime);
            }

            super.collectOperatingSystemCounters(scalars);
        }
    }

    /**
     * Write out the global machine counters for Linux.
     *
     * @param scalars
     */
    @Override
    protected void collectGlobalPerformanceInfo(Map scalars) {
        synchronized (this) {
            /**
             * The meminfo values for a Linux machine, that is the values that come from /proc/meminfo.
             */
            // /proc/meminfo is formatted on linux - use byte-counted output from free
            StringTokenizer st = readOutput("free -b", true); //$NON-NLS-1$
            if (st != null) {
                st.nextToken(); // throw away label
                long total = Long.parseLong(st.nextToken());
                long used = Long.parseLong(st.nextToken());
                long free = Long.parseLong(st.nextToken());
                st.nextToken(); // long shared;
                long buffers = Long.parseLong(st.nextToken());
                long cache = Long.parseLong(st.nextToken());

                addScalar(scalars, InternalDimensions.PHYSICAL_TOTAL, total);
                addScalar(scalars, InternalDimensions.USED_LINUX_MEM, used);
                addScalar(scalars, InternalDimensions.FREE_LINUX_MEM, free);
                addScalar(scalars, InternalDimensions.BUFFERS_LINUX, buffers);
                addScalar(scalars, InternalDimensions.SYSTEM_CACHE, cache);
            }
            super.collectGlobalPerformanceInfo(scalars);
        }
    }

    private StringTokenizer readTokens(String procPath, boolean skipFirst) {
        try (BufferedReader rdr = new BufferedReader(new FileReader(procPath));){
            if (skipFirst)
                rdr.readLine(); // throw away the heading line
            return new StringTokenizer(rdr.readLine());
        } catch (IOException e) {
            PerformanceTestPlugin.log(e);
        }
        return null;
    }

    private StringTokenizer readOutput(String cmd, boolean skipFirst) {
        BufferedReader rdr = null;
        try {
            Process process = Runtime.getRuntime().exec(cmd);
            rdr = new BufferedReader(new InputStreamReader(process.getInputStream()));
            if (skipFirst)
                rdr.readLine(); // throw away the heading line
            return new StringTokenizer(rdr.readLine());
        } catch (IOException e) {
            PerformanceTestPlugin.log(e);
        }
        finally {
            try {
                if (rdr != null)
                    rdr.close();
            } catch (IOException e) {
                // silently ignored
            }
        }
        return null;
    }
}
