// Copyright 2021 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 "secanomalyd/processes.h"

#include <algorithm>
#include <optional>

#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>

#include <brillo/process/process.h>

namespace secanomalyd {

namespace {
constexpr char kPsPath[] = "/bin/ps";
constexpr char kInitExecutable[] = "/sbin/init";
}  // namespace

ProcEntry::ProcEntry(base::StringPiece proc_str) {
  // These entries are of the form:
  //   3295 4026531836 ps              ps ax -o pid,pidns,comm,args

  std::vector<base::StringPiece> fields =
      base::SplitStringPiece(proc_str, base::kWhitespaceASCII,
                             base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  if (fields.size() < 4) {
    pid_ = -1;
    pidns_ = 0;
    return;
  }

  // PIDs are signed.
  if (!base::StringToInt(fields[0], &pid_)) {
    pid_ = -1;
  }

  // Namespace ids are inode numbers, inode numbers are unsigned.
  if (!base::StringToUint64(fields[1], &pidns_)) {
    pidns_ = 0;
  }
  comm_ = std::string(fields[2]);
  args_ =
      base::JoinString(base::make_span(fields.begin() + 3, fields.end()), " ");
}

MaybeProcEntries ReadProcesses(ProcessFilter filter) {
  std::unique_ptr<brillo::Process> reader(new brillo::ProcessImpl());
  return ReadProcesses(reader.get(), filter);
}

MaybeProcEntries ReadProcesses(brillo::Process* reader, ProcessFilter filter) {
  // Collect processes.
  // Call |ps| with a user defined format listing pid namespaces.
  reader->AddArg(kPsPath);
  // List all processes.
  reader->AddArg("ax");
  // List pid, pid namespace, executable name, and full command line.
  reader->AddStringOption("-o", "pid,pidns,comm,args");

  reader->RedirectUsingMemory(STDOUT_FILENO);
  if (reader->Run() != 0) {
    PLOG(ERROR) << "Failed to execute 'ps'";
    return std::nullopt;
  }

  std::string processes = reader->GetOutputString(STDOUT_FILENO);
  if (processes.empty()) {
    LOG(ERROR) << "Failed to read 'ps' output";
    return std::nullopt;
  }

  return ReadProcessesFromString(processes, filter);
}

MaybeProcEntries ReadProcessesFromString(const std::string& processes,
                                         ProcessFilter filter) {
  std::vector<base::StringPiece> pieces = base::SplitStringPiece(
      processes, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  if (pieces.empty()) {
    return std::nullopt;
  }

  ProcEntries res;
  std::optional<ino_t> init_pidns = std::nullopt;
  for (const auto& piece : pieces) {
    ProcEntry entry(piece);
    // Only add the entry to the list if it managed to parse a PID and a pidns.
    if (entry.pid() > 0 && entry.pidns() > 0) {
      if (filter == ProcessFilter::kInitPidNamespaceOnly &&
          entry.args() == std::string(kInitExecutable)) {
        init_pidns = entry.pidns();
        // The init process has been found, add it to the list and continue the
        // loop early.
        res.push_back(entry);
        continue;
      }

      // Add the entry to the list if:
      //    -Caller requested all processes, or
      //    -The init process hasn't yet been identified, or
      //    -The init process has been successfully identified, and the PID
      //     namespaces match.
      if (filter == ProcessFilter::kAll || !init_pidns ||
          entry.pidns() == init_pidns.value()) {
        res.push_back(entry);
      }
    }
  }

  if (filter == ProcessFilter::kInitPidNamespaceOnly) {
    if (init_pidns) {
      // Remove all processes whose |pidns| does not match init's.
      res.erase(std::remove_if(res.begin(), res.end(),
                               [init_pidns](const ProcEntry& pe) {
                                 return pe.pidns() != init_pidns.value();
                               }),
                res.end());
    } else {
      LOG(ERROR) << "Failed to find init process";
      return std::nullopt;
    }
  }

  // If we failed to parse any valid processes, return nullopt.
  return res.size() > 0 ? MaybeProcEntries(res) : std::nullopt;
}

}  // namespace secanomalyd
