// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "metrics/vmlog_writer.h"

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

#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/cpu.h>
#include <base/files/file.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/sys_info.h>
#include <brillo/daemons/daemon.h>

namespace chromeos_metrics {
namespace {

constexpr char kVmlogHeader[] =
    "time pgmajfault pgmajfault_f pgmajfault_a pswpin pswpout cpuusage";

// We limit the size of vmlog log files to keep frequent logging from wasting
// disk space.
constexpr int kMaxVmlogFileSize = 256 * 1024;

}  // namespace

bool VmStatsParseStats(std::istream* input_stream,
                       struct VmstatRecord* record) {
  // a mapping of string name to field in VmstatRecord and whether we found it
  struct Mapping {
    const std::string name;
    uint64_t* value_p;
    bool found;
    bool optional;
  } map[] = {
      {.name = "pgmajfault",
       .value_p = &record->page_faults_,
       .found = false,
       .optional = false},
      // pgmajfault_f and pgmajfault_a may not be present in all kernels.
      // Don't fuss if they are not.
      {.name = "pgmajfault_f",
       .value_p = &record->file_page_faults_,
       .found = false,
       .optional = true},
      {.name = "pgmajfault_a",
       .value_p = &record->anon_page_faults_,
       .found = false,
       .optional = true},
      {.name = "pswpin",
       .value_p = &record->swap_in_,
       .found = false,
       .optional = false},
      {.name = "pswpout",
       .value_p = &record->swap_out_,
       .found = false,
       .optional = false},
  };

  // Each line in the file has the form
  // <ID> <VALUE>
  // for instance:
  // nr_free_pages 213427
  std::string line;
  while (std::getline(*input_stream, line)) {
    std::vector<std::string> tokens = base::SplitString(
        line, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    if (tokens.size() != 2u) {
      LOG(WARNING) << "Unexpected vmstat format in line: " << line;
      continue;
    }
    for (auto& mapping : map) {
      if (!tokens[0].compare(mapping.name)) {
        if (!base::StringToUint64(tokens[1], mapping.value_p))
          return false;
        mapping.found = true;
      }
    }
  }
  // Make sure we got all the stats, except the optional ones.
  for (const auto& mapping : map) {
    if (!mapping.found) {
      if (mapping.optional) {
        *mapping.value_p = 0;
      } else {
        LOG(WARNING) << "vmstat missing " << mapping.name;
        return false;
      }
    }
  }
  return true;
}

bool ParseCpuTime(std::istream* input, CpuTimeRecord* record) {
  std::string buf;
  if (!std::getline(*input, buf)) {
    PLOG(ERROR) << "Unable to read cpu time";
    return false;
  }
  // Expect the first line to be like
  // cpu  20126642 15102603 12415348 2330408305 11759657 0 355204 0 0 0
  // The number corresponds to cpu time for
  // #cpu user nice system idle iowait irq softirq  steal guest guest_nice
  std::vector<std::string> tokens = base::SplitString(
      buf, " \t\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  if (tokens[0] != "cpu") {
    LOG(WARNING) << "Expect the first line of /proc/stat to be \"cpu ...\"";
    return false;
  }
  uint64_t value;
  for (int i = 1; i < tokens.size(); ++i) {
    if (!base::StringToUint64(tokens[i], &value)) {
      LOG(WARNING) << "Unable to convert " << tokens[i] << " to int64";
      return false;
    }
    record->total_time_ += value;
    // Exclude idle or iowait.
    if (i != 4 && i != 5) {
      record->non_idle_time_ += value;
    }
  }
  return true;
}

base::Optional<std::vector<int>> GetOnlineCpus(std::istream& proc_cpuinfo) {
  if (!proc_cpuinfo) {
    return base::nullopt;
  }

  // Search for lines like "processor : 0" in /proc/cpuinfo and add the CPU ID
  // part to the result list.
  std::vector<int> cpus;
  for (std::string line; std::getline(proc_cpuinfo, line);) {
    auto tokens = base::SplitString(line, ":", base::TRIM_WHITESPACE,
                                    base::SPLIT_WANT_ALL);
    if (tokens.size() != 2) {
      continue;
    }

    if (tokens[0] != "processor") {
      continue;
    }

    int cpu = 0;
    if (base::StringToInt(tokens[1], &cpu)) {
      cpus.push_back(cpu);
    }
  }

  return cpus;
}

GpuInfo::GpuInfo(std::unique_ptr<std::istream> gpu_freq_stream,
                 GpuInfo::GpuType gpu_type)
    : gpu_freq_stream_(std::move(gpu_freq_stream)), gpu_type_(gpu_type) {}

std::unique_ptr<GpuInfo> GpuInfo::Get() {
  std::unique_ptr<std::ifstream> gpu_freq_stream =
      std::make_unique<std::ifstream>();

  // Intel GPU detection.
  static const char* intel_gpu_freq_stream =
      "/sys/kernel/debug/dri/0/i915_frequency_info";
  gpu_freq_stream->open(intel_gpu_freq_stream);
  // Derefence |gpu_freq_stream| to check whether the file opens successfully.
  if (*gpu_freq_stream) {
    return base::WrapUnique(
        new GpuInfo(std::move(gpu_freq_stream), GpuInfo::GpuType::kIntel));
  }

  // AMD GPU detection.
  static const char* amd_gpu_freq_stream =
      "/sys/class/drm/card0/device/pp_dpm_sclk";
  gpu_freq_stream->open(amd_gpu_freq_stream);
  // Derefence |gpu_freq_stream| to check whether the file opens successfully.
  if (*gpu_freq_stream) {
    return base::WrapUnique(
        new GpuInfo(std::move(gpu_freq_stream), GpuInfo::GpuType::kAmd));
  }

  // Unknown GPU: return a null object with |gpu_freq_stream| unopened.
  return base::WrapUnique(
      new GpuInfo(std::move(gpu_freq_stream), GpuInfo::GpuType::kUnknown));
}

bool GpuInfo::GetCurrentFrequency(std::ostream& out) {
  if (is_unknown()) {
    PLOG(ERROR) << "Unable to parse frequency from unknown GPU type";
    return false;
  }

  DCHECK(*gpu_freq_stream_);
  if (!gpu_freq_stream_->seekg(0, std::ios_base::beg)) {
    PLOG(ERROR) << "Unable to seek GPU frequency info file";
    return false;
  }

  static const char* amdgpu_sclk_expression = R"(^\d: (\d{2,4})Mhz \*$)";
  static const char* intelgpu_curr_freq_expression =
      R"(^Actual freq: (\d{2,4}) MHz$)";
  const pcrecpp::RE gpu_freq_matcher(gpu_type_ == GpuType::kAmd
                                         ? amdgpu_sclk_expression
                                         : intelgpu_curr_freq_expression);

  std::string line;
  while (std::getline(*gpu_freq_stream_, line)) {
    std::string frequency_mhz;
    if (gpu_freq_matcher.FullMatch(line, &frequency_mhz)) {
      out << " " << frequency_mhz;
      return true;
    }
  }

  PLOG(ERROR) << "Unable to recognize GPU frequency";
  return false;
}

/* ********************** RAPL **************************** */

bool RAPLInfo::ReadUint64File(const base::FilePath& path, uint64_t* value_out) {
  DCHECK(value_out);

  std::string str;
  if (!base::ReadFileToString(path, &str)) {
    PLOG(ERROR) << "Unable to read from " << path.value();
    return false;
  }

  base::TrimWhitespaceASCII(str, base::TRIM_TRAILING, &str);
  if (!base::StringToUint64(str, value_out)) {
    PLOG(ERROR) << "Unable to parse \"" << str << "\" from " << path.value();
    return false;
  }
  return true;
}

RAPLInfo::RAPLInfo(std::unique_ptr<std::vector<PowerDomain>> power_domains,
                   RAPLInfo::CpuType cpu_type)
    : power_domains_(std::move(power_domains)), cpu_type_(cpu_type) {}

std::unique_ptr<RAPLInfo> RAPLInfo::Get() {
  // Path to the powercap driver sysfs interface, if it doesn't exist,
  // either the kernel is old w/o powercap driver, or it is not configured.
  constexpr const char kPowercapPath[] = "/sys/class/powercap";

  // Kernel v3.13+ supports powercap, it also requires a proper configuration
  // enabling it; leave a verbose footprint of the kernel string, and examine
  // whether or not the system supports the powercap driver.
  base::FilePath powercap_file_path(kPowercapPath);

  // No RAPL on this system.
  if (!base::PathExists(powercap_file_path)) {
    PLOG(ERROR) << "No powercap driver sysfs interface, couldn't find "
                << powercap_file_path.value();

    return base::WrapUnique(new RAPLInfo(0, RAPLInfo::CpuType::kUnknown));
  }

  std::unique_ptr<std::vector<PowerDomain>> power_domains =
      std::make_unique<std::vector<PowerDomain>>();

  std::string domain_name;

  // Probe the power domains and sub-domains.
  base::FilePath powercap_path(kPowercapPath);
  base::FileEnumerator dirs(powercap_path, false,
                            base::FileEnumerator::DIRECTORIES, "intel-rapl:*");
  for (base::FilePath dir = dirs.Next(); !dir.empty(); dir = dirs.Next()) {
    base::FilePath domain_file_path = dir.Append("name");
    base::FilePath energy_file_path = dir.Append("energy_uj");
    base::FilePath maxeng_file_path = dir.Append("max_energy_range_uj");
    uint64_t max_energy_uj;

    if (!base::PathExists(domain_file_path)) {
      PLOG(ERROR) << "Unable to find " << domain_file_path.value();
      continue;
    }
    if (!base::PathExists(energy_file_path)) {
      PLOG(ERROR) << "Unable to find " << energy_file_path.value();
      continue;
    }
    if (!base::PathExists(maxeng_file_path)) {
      PLOG(ERROR) << "Unable to find " << maxeng_file_path.value();
      continue;
    }

    base::ReadFileToString(domain_file_path, &domain_name);
    base::TrimWhitespaceASCII(domain_name, base::TRIM_ALL, &domain_name);

    ReadUint64File(maxeng_file_path, &max_energy_uj);
    power_domains->push_back({energy_file_path, domain_name, max_energy_uj});
  }

  if (power_domains->empty()) {
    PLOG(ERROR) << "No power domain found at " << powercap_file_path.value();
    return base::WrapUnique(new RAPLInfo(0, RAPLInfo::CpuType::kUnknown));
  }

  // As the enumeration above does not guarantee the order, transform the
  // paths in lexicographical order, make the collecting data in a style
  // of domain follows by sub-domain, it can be done by sorting.
  // e.g., package-0 psys core ... -> package-0 core ... psys
  std::sort(power_domains->begin(), power_domains->end());

  // Initialize base state for calculating delta later. RAPL works by
  // checking the delta between energy used to calculate power over time.
  // So we need to seed the state prior to the initial printout.
  const base::TimeTicks ticks_before = base::TimeTicks::Now();
  uint32_t num_domains = power_domains->size();
  for (int i = 0; i < num_domains; ++i) {
    ReadUint64File(power_domains->at(i).file_path,
                   &(power_domains->at(i).energy_before));
    power_domains->at(i).ticks_before = ticks_before;
  }

  return base::WrapUnique(
      new RAPLInfo(std::move(power_domains), RAPLInfo::CpuType::kIntel));
}

bool RAPLInfo::GetHeader(std::ostream& header) {
  if (is_unknown()) {
    PLOG(ERROR) << "Unable to parse RAPL from this CPU";
    return false;
  }

  // List out the text name of each power domain.
  for (const auto& domain : *power_domains_)
    header << " " << domain.name;

  return true;
}

// Get the power delta from the last reading and output it to the stream.
bool RAPLInfo::GetCurrentPower(std::ostream& out) {
  if (is_unknown()) {
    PLOG(ERROR) << "Unable to parse RAPL from this CPU";
    return false;
  }
  // Cap of a maximal reasonable power in Watts
  constexpr const double kMaxWatts = 1e3;

  for (auto& domain : *power_domains_) {
    ReadUint64File(domain.file_path, &(domain.energy_after));
    domain.ticks_after = base::TimeTicks::Now();
  }

  for (auto& domain : *power_domains_) {
    uint64_t energy_delta =
        (domain.energy_after >= domain.energy_before)
            ? domain.energy_after - domain.energy_before
            : domain.max_energy - domain.energy_before + domain.energy_after;

    const base::TimeDelta time_delta = domain.ticks_after - domain.ticks_before;

    double average_power = energy_delta / (time_delta.InSecondsF() * 1e6);

    // Skip enormous sample if the counter is reset during suspend-to-RAM
    if (average_power > kMaxWatts) {
      out << " skip";
      continue;
    }
    out << " " << std::setprecision(3) << std::fixed << average_power;
  }

  for (auto& domain : *power_domains_) {
    domain.energy_before = domain.energy_after;
    domain.ticks_before = domain.ticks_after;
  }

  return true;
}

VmlogFile::VmlogFile(const base::FilePath& live_path,
                     const base::FilePath& rotated_path,
                     const uint64_t max_size,
                     const std::string& header)
    : live_path_(live_path),
      rotated_path_(rotated_path),
      max_size_(max_size),
      header_(header) {
  fd_ = open(live_path_.value().c_str(), O_CREAT | O_RDWR | O_EXCL, 0644);
  if (fd_ != -1) {
    Write(header_);
  } else {
    PLOG(ERROR) << "Failed to open file: " << live_path_.value();
  }
}

VmlogFile::~VmlogFile() = default;

bool VmlogFile::Write(const std::string& data) {
  if (fd_ == -1)
    return false;

  if (cur_size_ + data.size() > max_size_) {
    if (!base::CopyFile(live_path_, rotated_path_)) {
      PLOG(ERROR) << "Could not copy vmlog to: " << rotated_path_.value();
    }
    base::FilePath rotated_path_dir = rotated_path_.DirName();
    base::FilePath rotated_symlink = rotated_path_dir.Append("vmlog.1.LATEST");
    if (!base::PathExists(rotated_symlink)) {
      if (!base::CreateSymbolicLink(rotated_path_, rotated_symlink)) {
        PLOG(ERROR) << "Unable to create symbolic link from "
                    << rotated_symlink.value() << " to "
                    << rotated_path_.value();
      }
    }

    if (HANDLE_EINTR(ftruncate(fd_, 0)) != 0) {
      PLOG(ERROR) << "Could not ftruncate() file";
      return false;
    }
    if (HANDLE_EINTR(lseek(fd_, 0, SEEK_SET)) != 0) {
      PLOG(ERROR) << "Could not lseek() file";
      return false;
    }
    cur_size_ = 0;
    if (!Write(header_)) {
      return false;
    }
  }

  if (!base::WriteFileDescriptor(fd_, data.c_str(), data.size())) {
    return false;
  }
  cur_size_ += data.size();
  return true;
}

VmlogWriter::VmlogWriter(const base::FilePath& vmlog_dir,
                         const base::TimeDelta& log_interval) {
  if (!base::DirectoryExists(vmlog_dir)) {
    if (!base::CreateDirectory(vmlog_dir)) {
      PLOG(ERROR) << "Couldn't create " << vmlog_dir.value();
      return;
    }
  }
  if (!base::SetPosixFilePermissions(vmlog_dir, 0755)) {
    PLOG(ERROR) << "Couldn't set permissions for " << vmlog_dir.value();
  }
  Init(vmlog_dir, log_interval);
}

void VmlogWriter::Init(const base::FilePath& vmlog_dir,
                       const base::TimeDelta& log_interval) {
  base::Time now = base::Time::Now();

  // If the current time is within a day of the epoch, we probably don't have a
  // good time set for naming files. Wait 5 minutes.
  //
  // See crbug.com/724175 for details.
  if (now - base::Time::UnixEpoch() < base::TimeDelta::FromDays(1)) {
    LOG(WARNING) << "Time seems incorrect, too close to epoch: " << now;
    valid_time_delay_timer_.Start(
        FROM_HERE, base::TimeDelta::FromMinutes(5),
        base::Bind(&VmlogWriter::Init, base::Unretained(this), vmlog_dir,
                   log_interval));
    return;
  }

  base::FilePath vmlog_current_path =
      vmlog_dir.Append("vmlog." + brillo::GetTimeAsLogString(now));
  base::FilePath vmlog_rotated_path =
      vmlog_dir.Append("vmlog.1." + brillo::GetTimeAsLogString(now));

  brillo::UpdateLogSymlinks(vmlog_dir.Append("vmlog.LATEST"),
                            vmlog_dir.Append("vmlog.PREVIOUS"),
                            vmlog_current_path);

  base::DeleteFile(vmlog_dir.Append("vmlog.1.PREVIOUS"), false);
  if (base::PathExists(vmlog_dir.Append("vmlog.1.LATEST"))) {
    base::Move(vmlog_dir.Append("vmlog.1.LATEST"),
               vmlog_dir.Append("vmlog.1.PREVIOUS"));
  }

  vmstat_stream_.open("/proc/vmstat", std::ifstream::in);
  if (vmstat_stream_.fail()) {
    PLOG(ERROR) << "Couldn't open /proc/vmstat";
    return;
  }

  proc_stat_stream_.open("/proc/stat", std::ifstream::in);
  if (proc_stat_stream_.fail()) {
    PLOG(ERROR) << "Couldn't open /proc/stat";
    return;
  }

  if (!log_interval.is_zero()) {
    timer_.Start(FROM_HERE, log_interval, this, &VmlogWriter::WriteCallback);
  }

  // The IDs of online CPUs are not necessarily in the set of [0,
  // sysconf(_SC_NPROCESSORS_ONLN) - 1]. Query the system to get the set of
  // online CPUs.
  std::ifstream proc_cpuinfo("/proc/cpuinfo");
  auto online_cpus = GetOnlineCpus(proc_cpuinfo);
  if (!online_cpus.has_value() || online_cpus->size() == 0) {
    PLOG(WARNING) << "Failed to get the list of online CPUs.";

    // Failed to parse online CPUs - fallback use the set of [0, n_cpus).
    const int n_cpus = sysconf(_SC_NPROCESSORS_ONLN);
    for (int cpu = 0; cpu != n_cpus; ++cpu) {
      online_cpus->emplace_back(cpu);
    }
  }

  for (auto cpu : *online_cpus) {
    std::ostringstream path;
    path << "/sys/devices/system/cpu/cpufreq/policy" << cpu
         << "/scaling_cur_freq";
    std::ifstream cpufreq_stream(path.str());
    if (cpufreq_stream) {
      cpufreq_streams_.push_back(std::move(cpufreq_stream));
    } else {
      PLOG(WARNING) << "Failed to open scaling_cur_freq for logical core "
                    << cpu;
    }
  }

  // Detect and open GPU frequency info stream.
  gpu_info_ = GpuInfo::Get();
  DCHECK(gpu_info_.get());

  std::ostringstream header(kVmlogHeader, std::ios_base::ate);
  if (!gpu_info_->is_unknown())
    header << " gpufreq";

  for (int cpu = 0; cpu != cpufreq_streams_.size(); ++cpu) {
    header << " cpufreq" << cpu;
  }

  rapl_info_ = RAPLInfo::Get();
  DCHECK(rapl_info_.get());

  if (!rapl_info_->is_unknown())
    rapl_info_->GetHeader(header);

  header << "\n";

  vmlog_.reset(new VmlogFile(vmlog_current_path, vmlog_rotated_path,
                             kMaxVmlogFileSize, header.str()));
}

VmlogWriter::~VmlogWriter() = default;

bool VmlogWriter::GetCpuUsage(double* cpu_usage_out) {
  proc_stat_stream_.clear();
  if (!proc_stat_stream_.seekg(0, std::ios_base::beg)) {
    PLOG(ERROR) << "Unable to seekg() /proc/stat";
    return false;
  }
  CpuTimeRecord cur;
  ParseCpuTime(&proc_stat_stream_, &cur);
  if (cur.total_time_ == prev_cputime_record_.total_time_) {
    LOG(WARNING) << "Same total time for two consecutive calls to GetCpuUsage";
    return false;
  }
  *cpu_usage_out =
      (cur.non_idle_time_ - prev_cputime_record_.non_idle_time_) /
      static_cast<double>(cur.total_time_ - prev_cputime_record_.total_time_);
  prev_cputime_record_ = cur;
  return true;
}

bool VmlogWriter::GetDeltaVmStat(VmstatRecord* delta_out) {
  // Reset the Vmstat stream.
  vmstat_stream_.clear();
  if (!vmstat_stream_.seekg(0, std::ios_base::beg)) {
    PLOG(ERROR) << "Unable to seekg() /proc/vmstat";
    return false;
  }

  // Get current Vmstat.
  VmstatRecord r;
  if (!VmStatsParseStats(&vmstat_stream_, &r)) {
    LOG(ERROR) << "Unable to parse vmstat data";
    return false;
  }

  delta_out->page_faults_ = r.page_faults_ - prev_vmstat_record_.page_faults_;
  delta_out->file_page_faults_ =
      r.file_page_faults_ - prev_vmstat_record_.file_page_faults_;
  delta_out->anon_page_faults_ =
      r.anon_page_faults_ - prev_vmstat_record_.anon_page_faults_;
  delta_out->swap_in_ = r.swap_in_ - prev_vmstat_record_.swap_in_;
  delta_out->swap_out_ = r.swap_out_ - prev_vmstat_record_.swap_out_;
  prev_vmstat_record_ = r;
  return true;
}

bool VmlogWriter::GetRAPL(std::ostream& out) {
  if (rapl_info_->is_unknown()) {
    // Nothing to do if the sysfs entry is not present.
    return true;
  }

  return rapl_info_->GetCurrentPower(out);
}

bool VmlogWriter::GetGpuFrequency(std::ostream& out) {
  if (gpu_info_->is_unknown()) {
    // Nothing to do if the sysfs entry is not present.
    return true;
  }

  return gpu_info_->GetCurrentFrequency(out);
}

bool VmlogWriter::GetCpuFrequencies(std::ostream& out) {
  for (std::ifstream& cpufreq_stream : cpufreq_streams_) {
    if (!cpufreq_stream.seekg(0, std::ios_base::beg)) {
      PLOG(ERROR) << "Unable to seek scaling_cur_freq";
      return false;
    }

    std::string result;
    cpufreq_stream >> result;
    out << " " << result;
  }
  return true;
}

void VmlogWriter::WriteCallback() {
  VmstatRecord delta_vmstat;
  double cpu_usage;
  if (!GetDeltaVmStat(&delta_vmstat) || !GetCpuUsage(&cpu_usage)) {
    LOG(ERROR) << "Stop timer because of error reading system info";
    timer_.Stop();
    return;
  }

  timeval tv;
  gettimeofday(&tv, nullptr);
  struct tm tm_time;
  localtime_r(&tv.tv_sec, &tm_time);
  std::ostringstream out_line;
  out_line << base::StringPrintf(
      "[%02d%02d/%02d%02d%02d]"
      " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %.2f",
      tm_time.tm_mon + 1, tm_time.tm_mday,              //
      tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,  //
      delta_vmstat.page_faults_, delta_vmstat.file_page_faults_,
      delta_vmstat.anon_page_faults_, delta_vmstat.swap_in_,
      delta_vmstat.swap_out_, cpu_usage);

  if (!GetGpuFrequency(out_line) || !GetCpuFrequencies(out_line) ||
      !GetRAPL(out_line)) {
    LOG(ERROR) << "Stop timer because of error reading system info";
    timer_.Stop();
  }
  out_line << "\n";

  if (!vmlog_->Write(out_line.str())) {
    LOG(ERROR) << "Writing to vmlog failed.";
    timer_.Stop();
    return;
  }
}

}  // namespace chromeos_metrics
