/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#include <fcntl.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <cinttypes>
#include <string>

#include "perfetto/base/logging.h"
#include "perfetto/base/time.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/getopt.h"
#include "perfetto/ext/base/scoped_file.h"

// Periodically prints an un-normalized cpu usage ratio (full use of a single
// core = 1.0) of a target process. Based on /proc/pid/stat utime (userspace) &
// stime (kernel space).

namespace perfetto {
namespace {

uint64_t TimespecToMs(struct timespec ts) {
  PERFETTO_CHECK(ts.tv_sec >= 0 && ts.tv_nsec >= 0);
  return static_cast<uint64_t>(ts.tv_sec) * 1000 +
         static_cast<uint64_t>(ts.tv_nsec) / 1000 / 1000;
}

uint64_t ReadWallTimeMs(clockid_t clk) {
  struct timespec ts = {};
  PERFETTO_CHECK(clock_gettime(clk, &ts) == 0);
  return TimespecToMs(ts);
}

void ReadUtimeStime(const base::ScopedFile& stat_fd,
                    unsigned long* utime_out,
                    unsigned long* stime_out) {
  char buf[1024] = {};
  lseek(stat_fd.get(), 0, SEEK_SET);
  PERFETTO_CHECK(read(stat_fd.get(), buf, sizeof(buf)) > 0);
  buf[sizeof(buf) - 1] = '\0';

  PERFETTO_CHECK(
      sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu",
             utime_out, stime_out) == 2);
}

int CpuUtilizationMain(int argc, char** argv) {
  unsigned sleep_duration_us = 10 * 1000 * 1000;  // 10s
  int sleep_intervals = 6;
  int target_pid = -1;

  static option long_options[] = {
      {"pid", required_argument, nullptr, 'p'},
      {"sleep-duration-us", required_argument, nullptr, 't'},
      {"sleep-intervals", required_argument, nullptr, 'n'},
      {nullptr, 0, nullptr, 0}};
  int c;
  while ((c = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
    switch (c) {
      case 'p':
        target_pid = atoi(optarg);
        break;
      case 't':
        sleep_duration_us = static_cast<unsigned>(atoi(optarg));
        break;
      case 'n':
        sleep_intervals = atoi(optarg);
        break;
      default:
        break;
    }
  }

  if (target_pid < 1) {
    PERFETTO_ELOG(
        "Usage: %s --pid=target_pid [--sleep-duration-us=N] "
        "[--sleep-intervals=N]",
        argv[0]);
    return 1;
  }

  // Resolution of utime/stime from procfs, at least 10 ms.
  long ticks = sysconf(_SC_CLK_TCK);
  PERFETTO_CHECK(ticks >= 100);
  unsigned long ticks_per_s = static_cast<unsigned long>(ticks);

  // Resolution of wallclock time, at least 1 ms. Should be O(ns) in practice.
  auto clk = CLOCK_MONOTONIC_RAW;
  struct timespec ts = {};
  PERFETTO_CHECK(clock_getres(clk, &ts) == 0);
  PERFETTO_CHECK(ts.tv_sec == 0 && ts.tv_nsec <= 1 * 1000 * 1000);

  PERFETTO_LOG("--- setup: ---");
  PERFETTO_LOG("target pid: %d", target_pid);
  PERFETTO_LOG("intervals: %d x %uus", sleep_intervals, sleep_duration_us);
  PERFETTO_LOG("utime/stime ticks per sec: %ld", ticks_per_s);
  PERFETTO_LOG("wall clock resolution (ns): %ld", ts.tv_nsec);
  PERFETTO_LOG("--- timings: ---");

  base::ScopedFile fd = base::OpenFile(
      std::string("/proc/") + std::to_string(target_pid) + std::string("/stat"),
      O_RDONLY);
  PERFETTO_CHECK(fd);

  // Read the base times.
  unsigned long first_utime = 0;
  unsigned long first_stime = 0;
  ReadUtimeStime(fd, &first_utime, &first_stime);
  uint64_t first_walltime_ms = ReadWallTimeMs(clk);

  uint64_t last_walltime_ms = first_walltime_ms;
  unsigned long last_utime = first_utime;
  unsigned long last_stime = first_stime;

  // Report the utilization for each fixed duration chunk.
  for (int i = 0; i < sleep_intervals; i++) {
    base::SleepMicroseconds(sleep_duration_us);

    unsigned long utime = 0;
    unsigned long stime = 0;
    ReadUtimeStime(fd, &utime, &stime);
    uint64_t walltime_ms = ReadWallTimeMs(clk);

    uint64_t wall_diff_ms = walltime_ms - last_walltime_ms;
    PERFETTO_LOG("wall_ms    : [%" PRIu64 "] - [%" PRIu64 "] = [%" PRIu64 "]",
                 walltime_ms, last_walltime_ms, wall_diff_ms);

    unsigned long utime_diff = utime - last_utime;
    unsigned long stime_diff = stime - last_stime;
    PERFETTO_LOG("utime_ticks: [%lu] - [%lu] = [%lu]", utime, last_utime,
                 utime_diff);
    PERFETTO_LOG("stime_ticks: [%lu] - [%lu] = [%lu]", stime, last_stime,
                 stime_diff);

    // Calculate the utilization, resolution of inputs will be no worse than
    // 10ms due to the above assert. At the default 10s wall time, we therefore
    // get a resolution of at least 0.1%.
    double utime_diff_ms = static_cast<double>(utime_diff * 1000 / ticks_per_s);
    double stime_diff_ms = static_cast<double>(stime_diff * 1000 / ticks_per_s);

    double utime_ratio = utime_diff_ms / static_cast<double>(wall_diff_ms);
    double stime_ratio = stime_diff_ms / static_cast<double>(wall_diff_ms);

    PERFETTO_LOG("utime ratio   : %f", utime_ratio);
    PERFETTO_LOG("stime ratio   : %f", stime_ratio);
    PERFETTO_LOG("combined ratio: %f\n", utime_ratio + stime_ratio);

    last_walltime_ms = walltime_ms;
    last_utime = utime;
    last_stime = stime;
  }

  PERFETTO_LOG("--- timings over the whole period: ---");
  unsigned long utime_diff = last_utime - first_utime;
  unsigned long stime_diff = last_stime - first_stime;
  uint64_t wall_diff_ms = last_walltime_ms - first_walltime_ms;
  double utime_diff_ms = static_cast<double>(utime_diff * 1000 / ticks_per_s);
  double stime_diff_ms = static_cast<double>(stime_diff * 1000 / ticks_per_s);
  double utime_ratio = utime_diff_ms / static_cast<double>(wall_diff_ms);
  double stime_ratio = stime_diff_ms / static_cast<double>(wall_diff_ms);
  PERFETTO_LOG("utime ratio   : %f", utime_ratio);
  PERFETTO_LOG("stime ratio   : %f", stime_ratio);
  PERFETTO_LOG("combined ratio: %f\n", utime_ratio + stime_ratio);

  return 0;
}

}  // namespace
}  // namespace perfetto

int main(int argc, char** argv) {
  return perfetto::CpuUtilizationMain(argc, argv);
}
