// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed 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 com.google.devtools.build.lib.util;

import static java.nio.charset.StandardCharsets.US_ASCII;

import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.io.Files;

import com.sun.management.OperatingSystemMXBean;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.util.Iterator;

/**
 * Provides methods to measure the current resource usage of the current
 * process. Also provides some convenience methods to obtain several system
 * characteristics, like number of processors , total memory, etc.
 */
public final class ResourceUsage {

  /*
   * Use com.sun.management.OperatingSystemMXBean instead of
   * java.lang.management.OperatingSystemMXBean because the latter does not
   * support getTotalPhysicalMemorySize() and getFreePhysicalMemorySize().
   */
  private static final OperatingSystemMXBean OS_BEAN =
      (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();

  private static final MemoryMXBean MEM_BEAN = ManagementFactory.getMemoryMXBean();
  private static final Splitter WHITESPACE_SPLITTER = Splitter.on(CharMatcher.whitespace());

  /**
   * Calculates an estimate of the current total CPU usage and the CPU usage of
   * the process in percent measured from the two given measurements. The
   * returned CPU usages rea average values for the time between the two
   * measurements. The returned array contains the total CPU usage at index 0
   * and the CPU usage of the measured process at index 1.
   */
  public static float[] calculateCurrentCpuUsage(Measurement oldMeasurement,
      Measurement newMeasurement) {
    if (oldMeasurement == null) {
      return new float[2];
    }
    long idleJiffies =
        newMeasurement.getTotalCpuIdleTimeInJiffies()
            - oldMeasurement.getTotalCpuIdleTimeInJiffies();
    long oldProcessJiffies =
        oldMeasurement.getCpuUtilizationInJiffies()[0]
            + oldMeasurement.getCpuUtilizationInJiffies()[1];
    long newProcessJiffies =
        newMeasurement.getCpuUtilizationInJiffies()[0]
            + newMeasurement.getCpuUtilizationInJiffies()[1];
    long processJiffies = newProcessJiffies - oldProcessJiffies;
    long elapsedTimeJiffies =
        newMeasurement.getTimeInJiffies() - oldMeasurement.getTimeInJiffies();
    int processors = getAvailableProcessors();
    // TODO(bazel-team): Sometimes smaller then zero. Not sure why.
    double totalUsage = Math.max(0, 1.0D - (double) idleJiffies / elapsedTimeJiffies / processors);
    double usage = Math.max(0, (double) processJiffies / elapsedTimeJiffies / processors);
    return new float[] {(float) totalUsage * 100, (float) usage * 100};
  }

  private ResourceUsage() {
  }

  /**
   * Returns the number of processors available to the Java virtual machine.
   */
  public static int getAvailableProcessors() {
    return OS_BEAN.getAvailableProcessors();
  }

  /**
   * Returns the total physical memory in bytes.
   */
  public static long getTotalPhysicalMemorySize() {
    return OS_BEAN.getTotalPhysicalMemorySize();
  }

  /**
   * Returns the operating system architecture.
   */
  public static String getOsArchitecture() {
    return OS_BEAN.getArch();
  }

  /**
   * Returns the operating system name.
   */
  public static String getOsName() {
    return OS_BEAN.getName();
  }

  /**
   * Returns the operating system version.
   */
  public static String getOsVersion() {
    return OS_BEAN.getVersion();
  }

  /**
   * Returns the initial size of heap memory in bytes.
   *
   * @see MemoryMXBean#getHeapMemoryUsage()
   */
  public static long getHeapMemoryInit() {
    return MEM_BEAN.getHeapMemoryUsage().getInit();
  }

  /**
   * Returns the initial size of non heap memory in bytes.
   *
   * @see MemoryMXBean#getNonHeapMemoryUsage()
   */
  public static long getNonHeapMemoryInit() {
    return MEM_BEAN.getNonHeapMemoryUsage().getInit();
  }

  /**
   * Returns the maximum size of heap memory in bytes.
   *
   * @see MemoryMXBean#getHeapMemoryUsage()
   */
  public static long getHeapMemoryMax() {
    return MEM_BEAN.getHeapMemoryUsage().getMax();
  }

  /**
   * Returns the maximum size of non heap memory in bytes.
   *
   * @see MemoryMXBean#getNonHeapMemoryUsage()
   */
  public static long getNonHeapMemoryMax() {
    return MEM_BEAN.getNonHeapMemoryUsage().getMax();
  }

  /**
   * Returns a measurement of the current resource usage of the current process.
   */
  public static Measurement measureCurrentResourceUsage() {
    return measureCurrentResourceUsage("self");
  }

  /**
   * Returns a measurement of the current resource usage of the process with the
   * given process id.
   *
   * @param processId the process id or <code>self</code> for the current
   *        process.
   */
  public static Measurement measureCurrentResourceUsage(String processId) {
    return new Measurement(MEM_BEAN.getHeapMemoryUsage().getUsed(), MEM_BEAN.getHeapMemoryUsage()
        .getCommitted(), MEM_BEAN.getNonHeapMemoryUsage().getUsed(), MEM_BEAN
        .getNonHeapMemoryUsage().getCommitted(), (float) OS_BEAN.getSystemLoadAverage(), OS_BEAN
        .getFreePhysicalMemorySize(), getCurrentTotalIdleTimeInJiffies(),
        getCurrentCpuUtilizationInJiffies(processId));
  }

  /**
   * Returns the current total idle time of the processors since system boot.
   * Reads /proc/stat to obtain this information.
   */
  private static long getCurrentTotalIdleTimeInJiffies() {
    try {
      File file = new File("/proc/stat");
      String content = Files.toString(file, US_ASCII);
      String value = Iterables.get(WHITESPACE_SPLITTER.split(content), 5);
      return Long.parseLong(value);
    } catch (NumberFormatException | IOException e) {
      return 0L;
    }
  }

  /**
   * Returns the current cpu utilization of the current process with the given
   * id in jiffies. The returned array contains the following information: The
   * 1st entry is the number of jiffies that the process has executed in user
   * mode, and the 2nd entry is the number of jiffies that the process has
   * executed in kernel mode. Reads /proc/self/stat to obtain this information.
   *
   * @param processId the process id or <code>self</code> for the current
   *        process.
   */
  private static long[] getCurrentCpuUtilizationInJiffies(String processId) {
    try {
      File file = new File("/proc/" + processId + "/stat");
      if (file.isDirectory()) {
        return new long[2];
      }
      Iterator<String> stat = WHITESPACE_SPLITTER.split(
          Files.toString(file, US_ASCII)).iterator();
      for (int i = 0; i < 13; ++i) {
        stat.next();
      }
      long token13 = Long.parseLong(stat.next());
      long token14 = Long.parseLong(stat.next());
      return new long[] { token13, token14 };
    } catch (NumberFormatException | IOException e) {
      return new long[2];
    }
  }

  /**
   * A snapshot of the resource usage of the current process at a point in time.
   */
  public static class Measurement {

    private final long timeInNanos;
    private final long heapMemoryUsed;
    private final long heapMemoryCommitted;
    private final long nonHeapMemoryUsed;
    private final long nonHeapMemoryCommitted;
    private final float loadAverageLastMinute;
    private final long freePhysicalMemory;
    private final long totalCpuIdleTimeInJiffies;
    private final long[] cpuUtilizationInJiffies;

    public Measurement(long heapMemoryUsed, long heapMemoryCommitted, long nonHeapMemoryUsed,
        long nonHeapMemoryCommitted, float loadAverageLastMinute, long freePhysicalMemory,
        long totalCpuIdleTimeInJiffies, long[] cpuUtilizationInJiffies) {
      super();
      timeInNanos = System.nanoTime();
      this.heapMemoryUsed = heapMemoryUsed;
      this.heapMemoryCommitted = heapMemoryCommitted;
      this.nonHeapMemoryUsed = nonHeapMemoryUsed;
      this.nonHeapMemoryCommitted = nonHeapMemoryCommitted;
      this.loadAverageLastMinute = loadAverageLastMinute;
      this.freePhysicalMemory = freePhysicalMemory;
      this.totalCpuIdleTimeInJiffies = totalCpuIdleTimeInJiffies;
      this.cpuUtilizationInJiffies = cpuUtilizationInJiffies;
    }

    /**
     * Returns the time of the measurement in jiffies.
     */
    public long getTimeInJiffies() {
      return timeInNanos / 10000000;
    }

    /**
     * Returns the time of the measurement in ms.
     */
    public long getTimeInMs() {
      return timeInNanos / 1000000;
    }

    /**
     * Returns the amount of used heap memory in bytes at the time of
     * measurement.
     *
     * @see MemoryMXBean#getHeapMemoryUsage()
     */
    public long getHeapMemoryUsed() {
      return heapMemoryUsed;
    }

    /**
     * Returns the amount of used non heap memory in bytes at the time of
     * measurement.
     *
     * @see MemoryMXBean#getNonHeapMemoryUsage()
     */
    public long getHeapMemoryCommitted() {
      return heapMemoryCommitted;
    }

    /**
     * Returns the amount of memory in bytes that is committed for the Java
     * virtual machine to use for the heap at the time of measurement.
     *
     * @see MemoryMXBean#getHeapMemoryUsage()
     */
    public long getNonHeapMemoryUsed() {
      return nonHeapMemoryUsed;
    }

    /**
     * Returns the amount of memory in bytes that is committed for the Java
     * virtual machine to use for non heap memory at the time of measurement.
     *
     * @see MemoryMXBean#getNonHeapMemoryUsage()
     */
    public long getNonHeapMemoryCommitted() {
      return nonHeapMemoryCommitted;
    }

    /**
     * Returns the system load average for the last minute at the time of
     * measurement.
     *
     * @see OperatingSystemMXBean#getSystemLoadAverage()
     */
    public float getLoadAverageLastMinute() {
      return loadAverageLastMinute;
    }

    /**
     * Returns the free physical memmory in bytes at the time of measurement.
     */
    public long getFreePhysicalMemory() {
      return freePhysicalMemory;
    }

    /**
     * Returns the current total cpu idle since system boot in jiffies.
     */
    public long getTotalCpuIdleTimeInJiffies() {
      return totalCpuIdleTimeInJiffies;
    }

    /**
     * Returns the current cpu utilization of the current process in jiffies.
     * The returned array contains the following information: The 1st entry is
     * the number of jiffies that the process has executed in user mode, and the
     * 2nd entry is the number of jiffies that the process has executed in
     * kernel mode. Reads /proc/self/stat to obtain this information.
     */
    public long[] getCpuUtilizationInJiffies() {
      return cpuUtilizationInJiffies;
    }

    /**
     * Returns the current cpu utilization of the current process in ms. The
     * returned array contains the following information: The 1st entry is the
     * number of ms that the process has executed in user mode, and the 2nd
     * entry is the number of ms that the process has executed in kernel mode.
     * Reads /proc/self/stat to obtain this information.
     */
    public long[] getCpuUtilizationInMs() {
      return new long[] {cpuUtilizationInJiffies[0] * 10, cpuUtilizationInJiffies[1] * 10};
    }
  }
}
