// Copyright 2018 The Chromium 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 "chrome/browser/ash/crostini/crosvm_process_list.h"

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

#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"

namespace crostini {

namespace {

// Reads a proc stat file whose pid is |pid|;
// inserts into |pid_stat_map| that maps from pid to its proc stat;
// inserts into |ppid_pids| the maps from its parent pid to its pid;
// assigns pid to |vm_concierge_pid| if this process is vm_concierge.
// |slash_proc| is "/proc" for production and is only changed for tests.
void ProcessProcStatFile(pid_t pid,
                         PidStatMap* pid_stat_map,
                         std::unordered_map<pid_t, std::set<pid_t>>* ppid_pids,
                         pid_t* vm_concierge_pid_out,
                         const base::FilePath& slash_proc) {
  base::FilePath file_path =
      slash_proc.Append(base::NumberToString(pid)).Append("stat");
  absl::optional<ash::system::SingleProcStat> stat =
      ash::system::GetSingleProcStat(file_path);
  if (!stat.has_value())
    return;

  pid_stat_map->emplace(pid, stat.value());
  if (stat.value().name == "vm_concierge") {
    if (*vm_concierge_pid_out != -1) {
      LOG(ERROR) << "More than one vm_concierge process found: "
                 << *vm_concierge_pid_out << " and " << pid << ".";
      *vm_concierge_pid_out = -1;
      return;
    }
    *vm_concierge_pid_out = pid;
  }
  auto it = ppid_pids->find(stat.value().ppid);
  if (it == ppid_pids->end()) {
    std::set<pid_t> pids({pid});
    ppid_pids->emplace(stat.value().ppid, std::move(pids));
  } else {
    it->second.emplace(pid);
  }
}

// Recursively insert |pid| and its children according to |ppid_pids| into
// |crosvm_pids|.
void InsertPid(pid_t pid,
               const std::unordered_map<pid_t, std::set<pid_t>>& ppid_pids,
               std::set<pid_t>* crosvm_pids) {
  DCHECK(crosvm_pids);
  crosvm_pids->insert(pid);
  auto it = ppid_pids.find(pid);
  if (it == ppid_pids.end())
    return;
  for (pid_t cpid : it->second) {
    if (crosvm_pids->find(cpid) != crosvm_pids->end())
      continue;
    InsertPid(cpid, ppid_pids, crosvm_pids);
  }
}

}  // namespace

PidStatMap GetCrosvmPidStatMap(const base::FilePath& slash_proc) {
  PidStatMap crosvm_process_map;
  PidStatMap all_process_map;
  pid_t vm_concierge_pid = -1;
  std::unordered_map<pid_t, std::set<pid_t>> ppid_pids;

  base::FileEnumerator slash_proc_file_enum(slash_proc, false /* recursive */,
                                            base::FileEnumerator::DIRECTORIES);
  for (base::FilePath name = slash_proc_file_enum.Next(); !name.empty();
       name = slash_proc_file_enum.Next()) {
    std::string pid_str = name.BaseName().value();
    pid_t pid;
    if (!base::StringToInt(pid_str, &pid)) {
      continue;
    }
    ProcessProcStatFile(pid, &all_process_map, &ppid_pids, &vm_concierge_pid,
                        slash_proc);
  }

  if (vm_concierge_pid == -1 || all_process_map.empty())
    return crosvm_process_map;

  std::set<pid_t> crosvm_pids;
  InsertPid(vm_concierge_pid, ppid_pids, &crosvm_pids);

  for (pid_t pid : crosvm_pids)
    crosvm_process_map.emplace(pid, all_process_map.at(pid));
  return crosvm_process_map;
}

}  // namespace crostini
