/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.appspot.apprtc;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Build;
import android.os.SystemClock;
import android.util.Log;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Simple CPU monitor.  The caller creates a CpuMonitor object which can then
 * be used via sampleCpuUtilization() to collect the percentual use of the
 * cumulative CPU capacity for all CPUs running at their nominal frequency.  3
 * values are generated: (1) getCpuCurrent() returns the use since the last
 * sampleCpuUtilization(), (2) getCpuAvg3() returns the use since 3 prior
 * calls, and (3) getCpuAvgAll() returns the use over all SAMPLE_SAVE_NUMBER
 * calls.
 *
 * <p>CPUs in Android are often "offline", and while this of course means 0 Hz
 * as current frequency, in this state we cannot even get their nominal
 * frequency.  We therefore tread carefully, and allow any CPU to be missing.
 * Missing CPUs are assumed to have the same nominal frequency as any close
 * lower-numbered CPU, but as soon as it is online, we'll get their proper
 * frequency and remember it.  (Since CPU 0 in practice always seem to be
 * online, this unidirectional frequency inheritance should be no problem in
 * practice.)
 *
 * <p>Caveats:
 *   o No provision made for zany "turbo" mode, common in the x86 world.
 *   o No provision made for ARM big.LITTLE; if CPU n can switch behind our
 *     back, we might get incorrect estimates.
 *   o This is not thread-safe.  To call asynchronously, create different
 *     CpuMonitor objects.
 *
 * <p>If we can gather enough info to generate a sensible result,
 * sampleCpuUtilization returns true.  It is designed to never throw an
 * exception.
 *
 * <p>sampleCpuUtilization should not be called too often in its present form,
 * since then deltas would be small and the percent values would fluctuate and
 * be unreadable. If it is desirable to call it more often than say once per
 * second, one would need to increase SAMPLE_SAVE_NUMBER and probably use
 * Queue<Integer> to avoid copying overhead.
 *
 * <p>Known problems:
 *   1. Nexus 7 devices running Kitkat have a kernel which often output an
 *      incorrect 'idle' field in /proc/stat.  The value is close to twice the
 *      correct value, and then returns to back to correct reading.  Both when
 *      jumping up and back down we might create faulty CPU load readings.
 */
@TargetApi(Build.VERSION_CODES.KITKAT)
class CpuMonitor {
  private static final String TAG = "CpuMonitor";
  private static final int MOVING_AVERAGE_SAMPLES = 5;

  private static final int CPU_STAT_SAMPLE_PERIOD_MS = 2000;
  private static final int CPU_STAT_LOG_PERIOD_MS = 6000;

  private final Context appContext;
  // User CPU usage at current frequency.
  private final MovingAverage userCpuUsage;
  // System CPU usage at current frequency.
  private final MovingAverage systemCpuUsage;
  // Total CPU usage relative to maximum frequency.
  private final MovingAverage totalCpuUsage;
  // CPU frequency in percentage from maximum.
  private final MovingAverage frequencyScale;

  private ScheduledExecutorService executor;
  private long lastStatLogTimeMs;
  private long[] cpuFreqMax;
  private int cpusPresent;
  private int actualCpusPresent;
  private boolean initialized;
  private boolean cpuOveruse;
  private String[] maxPath;
  private String[] curPath;
  private double[] curFreqScales;
  private ProcStat lastProcStat;

  private static class ProcStat {
    final long userTime;
    final long systemTime;
    final long idleTime;

    ProcStat(long userTime, long systemTime, long idleTime) {
      this.userTime = userTime;
      this.systemTime = systemTime;
      this.idleTime = idleTime;
    }
  }

  private static class MovingAverage {
    private final int size;
    private double sum;
    private double currentValue;
    private double[] circBuffer;
    private int circBufferIndex;

    public MovingAverage(int size) {
      if (size <= 0) {
        throw new AssertionError("Size value in MovingAverage ctor should be positive.");
      }
      this.size = size;
      circBuffer = new double[size];
    }

    public void reset() {
      Arrays.fill(circBuffer, 0);
      circBufferIndex = 0;
      sum = 0;
      currentValue = 0;
    }

    public void addValue(double value) {
      sum -= circBuffer[circBufferIndex];
      circBuffer[circBufferIndex++] = value;
      currentValue = value;
      sum += value;
      if (circBufferIndex >= size) {
        circBufferIndex = 0;
      }
    }

    public double getCurrent() {
      return currentValue;
    }

    public double getAverage() {
      return sum / (double) size;
    }
  }

  public static boolean isSupported() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
        && Build.VERSION.SDK_INT < Build.VERSION_CODES.N;
  }

  public CpuMonitor(Context context) {
    if (!isSupported()) {
      throw new RuntimeException("CpuMonitor is not supported on this Android version.");
    }

    Log.d(TAG, "CpuMonitor ctor.");
    appContext = context.getApplicationContext();
    userCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES);
    systemCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES);
    totalCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES);
    frequencyScale = new MovingAverage(MOVING_AVERAGE_SAMPLES);
    lastStatLogTimeMs = SystemClock.elapsedRealtime();

    scheduleCpuUtilizationTask();
  }

  public void pause() {
    if (executor != null) {
      Log.d(TAG, "pause");
      executor.shutdownNow();
      executor = null;
    }
  }

  public void resume() {
    Log.d(TAG, "resume");
    resetStat();
    scheduleCpuUtilizationTask();
  }

  // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression.
  @SuppressWarnings("NoSynchronizedMethodCheck")
  public synchronized void reset() {
    if (executor != null) {
      Log.d(TAG, "reset");
      resetStat();
      cpuOveruse = false;
    }
  }

  // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression.
  @SuppressWarnings("NoSynchronizedMethodCheck")
  public synchronized int getCpuUsageCurrent() {
    return doubleToPercent(userCpuUsage.getCurrent() + systemCpuUsage.getCurrent());
  }

  // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression.
  @SuppressWarnings("NoSynchronizedMethodCheck")
  public synchronized int getCpuUsageAverage() {
    return doubleToPercent(userCpuUsage.getAverage() + systemCpuUsage.getAverage());
  }

  // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression.
  @SuppressWarnings("NoSynchronizedMethodCheck")
  public synchronized int getFrequencyScaleAverage() {
    return doubleToPercent(frequencyScale.getAverage());
  }

  private void scheduleCpuUtilizationTask() {
    if (executor != null) {
      executor.shutdownNow();
      executor = null;
    }

    executor = Executors.newSingleThreadScheduledExecutor();
    @SuppressWarnings("unused") // Prevent downstream linter warnings.
    Future<?> possiblyIgnoredError = executor.scheduleAtFixedRate(new Runnable() {
      @Override
      public void run() {
        cpuUtilizationTask();
      }
    }, 0, CPU_STAT_SAMPLE_PERIOD_MS, TimeUnit.MILLISECONDS);
  }

  private void cpuUtilizationTask() {
    boolean cpuMonitorAvailable = sampleCpuUtilization();
    if (cpuMonitorAvailable
        && SystemClock.elapsedRealtime() - lastStatLogTimeMs >= CPU_STAT_LOG_PERIOD_MS) {
      lastStatLogTimeMs = SystemClock.elapsedRealtime();
      String statString = getStatString();
      Log.d(TAG, statString);
    }
  }

  private void init() {
    try (FileInputStream fin = new FileInputStream("/sys/devices/system/cpu/present");
         InputStreamReader streamReader = new InputStreamReader(fin, Charset.forName("UTF-8"));
         BufferedReader reader = new BufferedReader(streamReader);
         Scanner scanner = new Scanner(reader).useDelimiter("[-\n]");) {
      scanner.nextInt(); // Skip leading number 0.
      cpusPresent = 1 + scanner.nextInt();
      scanner.close();
    } catch (FileNotFoundException e) {
      Log.e(TAG, "Cannot do CPU stats since /sys/devices/system/cpu/present is missing");
    } catch (IOException e) {
      Log.e(TAG, "Error closing file");
    } catch (Exception e) {
      Log.e(TAG, "Cannot do CPU stats due to /sys/devices/system/cpu/present parsing problem");
    }

    cpuFreqMax = new long[cpusPresent];
    maxPath = new String[cpusPresent];
    curPath = new String[cpusPresent];
    curFreqScales = new double[cpusPresent];
    for (int i = 0; i < cpusPresent; i++) {
      cpuFreqMax[i] = 0; // Frequency "not yet determined".
      curFreqScales[i] = 0;
      maxPath[i] = "/sys/devices/system/cpu/cpu" + i + "/cpufreq/cpuinfo_max_freq";
      curPath[i] = "/sys/devices/system/cpu/cpu" + i + "/cpufreq/scaling_cur_freq";
    }

    lastProcStat = new ProcStat(0, 0, 0);
    resetStat();

    initialized = true;
  }

  private synchronized void resetStat() {
    userCpuUsage.reset();
    systemCpuUsage.reset();
    totalCpuUsage.reset();
    frequencyScale.reset();
    lastStatLogTimeMs = SystemClock.elapsedRealtime();
  }

  private int getBatteryLevel() {
    // Use sticky broadcast with null receiver to read battery level once only.
    Intent intent = appContext.registerReceiver(
        null /* receiver */, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

    int batteryLevel = 0;
    int batteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
    if (batteryScale > 0) {
      batteryLevel =
          (int) (100f * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0) / batteryScale);
    }
    return batteryLevel;
  }

  /**
   * Re-measure CPU use.  Call this method at an interval of around 1/s.
   * This method returns true on success.  The fields
   * cpuCurrent, cpuAvg3, and cpuAvgAll are updated on success, and represents:
   * cpuCurrent: The CPU use since the last sampleCpuUtilization call.
   * cpuAvg3: The average CPU over the last 3 calls.
   * cpuAvgAll: The average CPU over the last SAMPLE_SAVE_NUMBER calls.
   */
  private synchronized boolean sampleCpuUtilization() {
    long lastSeenMaxFreq = 0;
    long cpuFreqCurSum = 0;
    long cpuFreqMaxSum = 0;

    if (!initialized) {
      init();
    }
    if (cpusPresent == 0) {
      return false;
    }

    actualCpusPresent = 0;
    for (int i = 0; i < cpusPresent; i++) {
      /*
       * For each CPU, attempt to first read its max frequency, then its
       * current frequency.  Once as the max frequency for a CPU is found,
       * save it in cpuFreqMax[].
       */

      curFreqScales[i] = 0;
      if (cpuFreqMax[i] == 0) {
        // We have never found this CPU's max frequency.  Attempt to read it.
        long cpufreqMax = readFreqFromFile(maxPath[i]);
        if (cpufreqMax > 0) {
          Log.d(TAG, "Core " + i + ". Max frequency: " + cpufreqMax);
          lastSeenMaxFreq = cpufreqMax;
          cpuFreqMax[i] = cpufreqMax;
          maxPath[i] = null; // Kill path to free its memory.
        }
      } else {
        lastSeenMaxFreq = cpuFreqMax[i]; // A valid, previously read value.
      }

      long cpuFreqCur = readFreqFromFile(curPath[i]);
      if (cpuFreqCur == 0 && lastSeenMaxFreq == 0) {
        // No current frequency information for this CPU core - ignore it.
        continue;
      }
      if (cpuFreqCur > 0) {
        actualCpusPresent++;
      }
      cpuFreqCurSum += cpuFreqCur;

      /* Here, lastSeenMaxFreq might come from
       * 1. cpuFreq[i], or
       * 2. a previous iteration, or
       * 3. a newly read value, or
       * 4. hypothetically from the pre-loop dummy.
       */
      cpuFreqMaxSum += lastSeenMaxFreq;
      if (lastSeenMaxFreq > 0) {
        curFreqScales[i] = (double) cpuFreqCur / lastSeenMaxFreq;
      }
    }

    if (cpuFreqCurSum == 0 || cpuFreqMaxSum == 0) {
      Log.e(TAG, "Could not read max or current frequency for any CPU");
      return false;
    }

    /*
     * Since the cycle counts are for the period between the last invocation
     * and this present one, we average the percentual CPU frequencies between
     * now and the beginning of the measurement period.  This is significantly
     * incorrect only if the frequencies have peeked or dropped in between the
     * invocations.
     */
    double currentFrequencyScale = cpuFreqCurSum / (double) cpuFreqMaxSum;
    if (frequencyScale.getCurrent() > 0) {
      currentFrequencyScale = (frequencyScale.getCurrent() + currentFrequencyScale) * 0.5;
    }

    ProcStat procStat = readProcStat();
    if (procStat == null) {
      return false;
    }

    long diffUserTime = procStat.userTime - lastProcStat.userTime;
    long diffSystemTime = procStat.systemTime - lastProcStat.systemTime;
    long diffIdleTime = procStat.idleTime - lastProcStat.idleTime;
    long allTime = diffUserTime + diffSystemTime + diffIdleTime;

    if (currentFrequencyScale == 0 || allTime == 0) {
      return false;
    }

    // Update statistics.
    frequencyScale.addValue(currentFrequencyScale);

    double currentUserCpuUsage = diffUserTime / (double) allTime;
    userCpuUsage.addValue(currentUserCpuUsage);

    double currentSystemCpuUsage = diffSystemTime / (double) allTime;
    systemCpuUsage.addValue(currentSystemCpuUsage);

    double currentTotalCpuUsage =
        (currentUserCpuUsage + currentSystemCpuUsage) * currentFrequencyScale;
    totalCpuUsage.addValue(currentTotalCpuUsage);

    // Save new measurements for next round's deltas.
    lastProcStat = procStat;

    return true;
  }

  private int doubleToPercent(double d) {
    return (int) (d * 100 + 0.5);
  }

  private synchronized String getStatString() {
    StringBuilder stat = new StringBuilder();
    stat.append("CPU User: ")
        .append(doubleToPercent(userCpuUsage.getCurrent()))
        .append("/")
        .append(doubleToPercent(userCpuUsage.getAverage()))
        .append(". System: ")
        .append(doubleToPercent(systemCpuUsage.getCurrent()))
        .append("/")
        .append(doubleToPercent(systemCpuUsage.getAverage()))
        .append(". Freq: ")
        .append(doubleToPercent(frequencyScale.getCurrent()))
        .append("/")
        .append(doubleToPercent(frequencyScale.getAverage()))
        .append(". Total usage: ")
        .append(doubleToPercent(totalCpuUsage.getCurrent()))
        .append("/")
        .append(doubleToPercent(totalCpuUsage.getAverage()))
        .append(". Cores: ")
        .append(actualCpusPresent);
    stat.append("( ");
    for (int i = 0; i < cpusPresent; i++) {
      stat.append(doubleToPercent(curFreqScales[i])).append(" ");
    }
    stat.append("). Battery: ").append(getBatteryLevel());
    if (cpuOveruse) {
      stat.append(". Overuse.");
    }
    return stat.toString();
  }

  /**
   * Read a single integer value from the named file.  Return the read value
   * or if an error occurs return 0.
   */
  private long readFreqFromFile(String fileName) {
    long number = 0;
    try (FileInputStream stream = new FileInputStream(fileName);
         InputStreamReader streamReader = new InputStreamReader(stream, Charset.forName("UTF-8"));
         BufferedReader reader = new BufferedReader(streamReader)) {
      String line = reader.readLine();
      number = parseLong(line);
    } catch (FileNotFoundException e) {
      // CPU core is off, so file with its scaling frequency .../cpufreq/scaling_cur_freq
      // is not present. This is not an error.
    } catch (IOException e) {
      // CPU core is off, so file with its scaling frequency .../cpufreq/scaling_cur_freq
      // is empty. This is not an error.
    }
    return number;
  }

  private static long parseLong(String value) {
    long number = 0;
    try {
      number = Long.parseLong(value);
    } catch (NumberFormatException e) {
      Log.e(TAG, "parseLong error.", e);
    }
    return number;
  }

  /*
   * Read the current utilization of all CPUs using the cumulative first line
   * of /proc/stat.
   */
  @SuppressWarnings("StringSplitter")
  private ProcStat readProcStat() {
    long userTime = 0;
    long systemTime = 0;
    long idleTime = 0;
    try (FileInputStream stream = new FileInputStream("/proc/stat");
         InputStreamReader streamReader = new InputStreamReader(stream, Charset.forName("UTF-8"));
         BufferedReader reader = new BufferedReader(streamReader)) {
      // line should contain something like this:
      // cpu  5093818 271838 3512830 165934119 101374 447076 272086 0 0 0
      //       user    nice  system     idle   iowait  irq   softirq
      String line = reader.readLine();
      String[] lines = line.split("\\s+");
      int length = lines.length;
      if (length >= 5) {
        userTime = parseLong(lines[1]); // user
        userTime += parseLong(lines[2]); // nice
        systemTime = parseLong(lines[3]); // system
        idleTime = parseLong(lines[4]); // idle
      }
      if (length >= 8) {
        userTime += parseLong(lines[5]); // iowait
        systemTime += parseLong(lines[6]); // irq
        systemTime += parseLong(lines[7]); // softirq
      }
    } catch (FileNotFoundException e) {
      Log.e(TAG, "Cannot open /proc/stat for reading", e);
      return null;
    } catch (Exception e) {
      Log.e(TAG, "Problems parsing /proc/stat", e);
      return null;
    }
    return new ProcStat(userTime, systemTime, idleTime);
  }
}
