/*
 * Copyright (C) 2018 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 "src/profiling/common/proc_utils.h"

#include <sys/stat.h>
#include <unistd.h>

#include <cinttypes>

#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_utils.h"
#include "src/profiling/common/proc_cmdline.h"

namespace perfetto {
namespace profiling {
namespace {

base::Optional<uint32_t> ParseProcStatusSize(const std::string& status,
                                             const std::string& key) {
  auto entry_idx = status.find(key);
  if (entry_idx == std::string::npos)
    return {};
  entry_idx = status.find_first_not_of(" \t", entry_idx + key.size());
  if (entry_idx == std::string::npos)
    return {};
  int32_t val = atoi(status.c_str() + entry_idx);
  if (val < 0) {
    PERFETTO_ELOG("Unexpected value reading %s", key.c_str());
    return {};
  }
  return static_cast<uint32_t>(val);
}
}  // namespace

base::Optional<std::string> ReadStatus(pid_t pid) {
  std::string path = "/proc/" + std::to_string(pid) + "/status";
  std::string status;
  bool read_proc = base::ReadFile(path, &status);
  if (!read_proc) {
    PERFETTO_ELOG("Failed to read %s", path.c_str());
    return base::nullopt;
  }
  return base::Optional<std::string>(status);
}

base::Optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
  auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
  auto swap = ParseProcStatusSize(status, "VmSwap:");
  if (anon_rss.has_value() && swap.has_value()) {
    return *anon_rss + *swap;
  }
  return base::nullopt;
}

void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
  for (auto it = pids->begin(); it != pids->end();) {
    const pid_t pid = *it;

    base::Optional<std::string> status = ReadStatus(pid);
    base::Optional<uint32_t> rss_and_swap;
    if (status)
      rss_and_swap = GetRssAnonAndSwap(*status);

    if (rss_and_swap && rss_and_swap < min_size_kb) {
      PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB < %" PRIu32
                   ")",
                   pid, *rss_and_swap, min_size_kb);
      it = pids->erase(it);
    } else {
      ++it;
    }
  }
}

base::Optional<Uids> GetUids(const std::string& status) {
  auto entry_idx = status.find("Uid:");
  if (entry_idx == std::string::npos)
    return base::nullopt;

  Uids uids;
  const char* str = &status[entry_idx + 4];
  char* endptr;

  uids.real = strtoull(str, &endptr, 10);
  if (*endptr != ' ' && *endptr != '\t')
    return base::nullopt;

  str = endptr;
  uids.effective = strtoull(str, &endptr, 10);
  if (*endptr != ' ' && *endptr != '\t')
    return base::nullopt;

  str = endptr;
  uids.saved_set = strtoull(str, &endptr, 10);
  if (*endptr != ' ' && *endptr != '\t')
    return base::nullopt;

  str = endptr;
  uids.filesystem = strtoull(str, &endptr, 10);
  if (*endptr != '\n' && *endptr != '\0')
    return base::nullopt;
  return uids;
}

// Normalize cmdline in place. Stores new beginning of string in *cmdline_ptr.
// Returns new size of string (from new beginning).
// Modifies string in *cmdline_ptr.
ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size) {
  char* cmdline = *cmdline_ptr;
  char* first_arg = static_cast<char*>(memchr(cmdline, '\0', size));
  if (first_arg == nullptr) {
    errno = EOVERFLOW;
    return -1;
  }
  // For consistency with what we do with Java app cmdlines, trim everything
  // after the @ sign of the first arg.
  char* first_at = static_cast<char*>(memchr(cmdline, '@', size));
  if (first_at != nullptr && first_at < first_arg) {
    *first_at = '\0';
    first_arg = first_at;
  }
  char* start = static_cast<char*>(
      memrchr(cmdline, '/', static_cast<size_t>(first_arg - cmdline)));
  if (start == nullptr) {
    start = cmdline;
  } else {
    // Skip the /.
    start++;
  }
  *cmdline_ptr = start;
  return first_arg - start;
}

base::Optional<std::vector<std::string>> NormalizeCmdlines(
    const std::vector<std::string>& cmdlines) {
  std::vector<std::string> normalized_cmdlines;
  normalized_cmdlines.reserve(cmdlines.size());

  for (size_t i = 0; i < cmdlines.size(); i++) {
    std::string cmdline = cmdlines[i];  // mutable copy
    // Add nullbyte to make sure it's a C string.
    cmdline.resize(cmdline.size() + 1, '\0');
    char* cmdline_cstr = &(cmdline[0]);
    ssize_t size = NormalizeCmdLine(&cmdline_cstr, cmdline.size());
    if (size == -1) {
      PERFETTO_PLOG("Failed to normalize cmdline %s. Stopping the parse.",
                    cmdlines[i].c_str());
      return base::nullopt;
    }
    normalized_cmdlines.emplace_back(cmdline_cstr, static_cast<size_t>(size));
  }
  return base::make_optional(normalized_cmdlines);
}

// This is mostly the same as GetHeapprofdProgramProperty in
// https://android.googlesource.com/platform/bionic/+/master/libc/bionic/malloc_common.cpp
// This should give the same result as GetHeapprofdProgramProperty.
bool GetCmdlineForPID(pid_t pid, std::string* name) {
  std::string filename = "/proc/" + std::to_string(pid) + "/cmdline";
  base::ScopedFile fd(base::OpenFile(filename, O_RDONLY | O_CLOEXEC));
  if (!fd) {
    PERFETTO_DPLOG("Failed to open %s", filename.c_str());
    return false;
  }
  char cmdline[512];
  const size_t max_read_size = sizeof(cmdline) - 1;
  ssize_t rd = read(*fd, cmdline, max_read_size);
  if (rd == -1) {
    PERFETTO_DPLOG("Failed to read %s", filename.c_str());
    return false;
  }

  if (rd == 0) {
    PERFETTO_DLOG("Empty cmdline for %" PRIdMAX ". Skipping.",
                  static_cast<intmax_t>(pid));
    return false;
  }

  // In some buggy kernels (before http://bit.ly/37R7qwL) /proc/pid/cmdline is
  // not NUL-terminated (see b/147438623). If we read < max_read_size bytes
  // assume we are hitting the aforementioned kernel bug and terminate anyways.
  const size_t rd_u = static_cast<size_t>(rd);
  if (rd_u >= max_read_size && memchr(cmdline, '\0', rd_u) == nullptr) {
    // We did not manage to read the first argument.
    PERFETTO_DLOG("Overflow reading cmdline for %" PRIdMAX,
                  static_cast<intmax_t>(pid));
    errno = EOVERFLOW;
    return false;
  }

  cmdline[rd] = '\0';
  char* cmdline_start = cmdline;
  ssize_t size = NormalizeCmdLine(&cmdline_start, rd_u);
  if (size == -1)
    return false;
  name->assign(cmdline_start, static_cast<size_t>(size));
  return true;
}

void FindAllProfilablePids(std::set<pid_t>* pids) {
  ForEachPid([pids](pid_t pid) {
    if (pid == getpid())
      return;

    char filename_buf[128];
    snprintf(filename_buf, sizeof(filename_buf), "/proc/%d/%s", pid, "cmdline");
    struct stat statbuf;
    // Check if we have permission to the process.
    if (stat(filename_buf, &statbuf) == 0)
      pids->emplace(pid);
  });
}

void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
                         std::set<pid_t>* pids) {
  ForEachPid([&cmdlines, pids](pid_t pid) {
    if (pid == getpid())
      return;
    std::string process_cmdline;
    process_cmdline.reserve(512);
    GetCmdlineForPID(pid, &process_cmdline);
    for (const std::string& cmdline : cmdlines) {
      if (process_cmdline == cmdline)
        pids->emplace(static_cast<pid_t>(pid));
    }
  });
}

namespace glob_aware {
void FindPidsForCmdlinePatterns(const std::vector<std::string>& patterns,
                                std::set<pid_t>* pids) {
  ForEachPid([&patterns, pids](pid_t pid) {
    if (pid == getpid())
      return;
    std::string cmdline;
    if (!glob_aware::ReadProcCmdlineForPID(pid, &cmdline))
      return;
    const char* binname =
        glob_aware::FindBinaryName(cmdline.c_str(), cmdline.size());

    for (const std::string& pattern : patterns) {
      if (glob_aware::MatchGlobPattern(pattern.c_str(), cmdline.c_str(),
                                       binname)) {
        pids->insert(pid);
      }
    }
  });
}
}  // namespace glob_aware

}  // namespace profiling
}  // namespace perfetto
