/*
 *  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.support.annotation.Nullable;
import android.util.Log;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
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;

  @Nullable
  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;
  @Nullable
  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 @Nullable 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);
  }
}
