//===-- ProcessInfo.h -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_UTILITY_PROCESSINFO_H
#define LLDB_UTILITY_PROCESSINFO_H

#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Environment.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/NameMatches.h"
#include "llvm/Support/YAMLTraits.h"
#include <vector>

namespace lldb_private {

class UserIDResolver;

// ProcessInfo
//
// A base class for information for a process. This can be used to fill
// out information for a process prior to launching it, or it can be used for
// an instance of a process and can be filled in with the existing values for
// that process.
class ProcessInfo {
public:
  ProcessInfo();

  ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid);

  void Clear();

  const char *GetName() const;

  llvm::StringRef GetNameAsStringRef() const;

  FileSpec &GetExecutableFile() { return m_executable; }

  void SetExecutableFile(const FileSpec &exe_file,
                         bool add_exe_file_as_first_arg);

  const FileSpec &GetExecutableFile() const { return m_executable; }

  uint32_t GetUserID() const { return m_uid; }

  uint32_t GetGroupID() const { return m_gid; }

  bool UserIDIsValid() const { return m_uid != UINT32_MAX; }

  bool GroupIDIsValid() const { return m_gid != UINT32_MAX; }

  void SetUserID(uint32_t uid) { m_uid = uid; }

  void SetGroupID(uint32_t gid) { m_gid = gid; }

  ArchSpec &GetArchitecture() { return m_arch; }

  const ArchSpec &GetArchitecture() const { return m_arch; }

  void SetArchitecture(const ArchSpec &arch) { m_arch = arch; }

  lldb::pid_t GetProcessID() const { return m_pid; }

  void SetProcessID(lldb::pid_t pid) { m_pid = pid; }

  bool ProcessIDIsValid() const { return m_pid != LLDB_INVALID_PROCESS_ID; }

  void Dump(Stream &s, Platform *platform) const;

  Args &GetArguments() { return m_arguments; }

  const Args &GetArguments() const { return m_arguments; }

  llvm::StringRef GetArg0() const;

  void SetArg0(llvm::StringRef arg);

  void SetArguments(const Args &args, bool first_arg_is_executable);

  void SetArguments(char const **argv, bool first_arg_is_executable);

  Environment &GetEnvironment() { return m_environment; }
  const Environment &GetEnvironment() const { return m_environment; }

protected:
  template <class T> friend struct llvm::yaml::MappingTraits;
  FileSpec m_executable;
  std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
  // Not all process plug-ins support specifying an argv[0] that differs from
  // the resolved platform executable (which is in m_executable)
  Args m_arguments; // All program arguments except argv[0]
  Environment m_environment;
  uint32_t m_uid = UINT32_MAX;
  uint32_t m_gid = UINT32_MAX;
  ArchSpec m_arch;
  lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID;
};

// ProcessInstanceInfo
//
// Describes an existing process and any discoverable information that pertains
// to that process.
class ProcessInstanceInfo : public ProcessInfo {
public:
  ProcessInstanceInfo() : ProcessInfo() {}

  ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid)
      : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX),
        m_parent_pid(LLDB_INVALID_PROCESS_ID) {}

  void Clear() {
    ProcessInfo::Clear();
    m_euid = UINT32_MAX;
    m_egid = UINT32_MAX;
    m_parent_pid = LLDB_INVALID_PROCESS_ID;
  }

  uint32_t GetEffectiveUserID() const { return m_euid; }

  uint32_t GetEffectiveGroupID() const { return m_egid; }

  bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; }

  bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; }

  void SetEffectiveUserID(uint32_t uid) { m_euid = uid; }

  void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; }

  lldb::pid_t GetParentProcessID() const { return m_parent_pid; }

  void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; }

  bool ParentProcessIDIsValid() const {
    return m_parent_pid != LLDB_INVALID_PROCESS_ID;
  }

  void Dump(Stream &s, UserIDResolver &resolver) const;

  static void DumpTableHeader(Stream &s, bool show_args, bool verbose);

  void DumpAsTableRow(Stream &s, UserIDResolver &resolver, bool show_args,
                      bool verbose) const;

protected:
  friend struct llvm::yaml::MappingTraits<ProcessInstanceInfo>;
  uint32_t m_euid = UINT32_MAX;
  uint32_t m_egid = UINT32_MAX;
  lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID;
};

typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;

// ProcessInstanceInfoMatch
//
// A class to help matching one ProcessInstanceInfo to another.

class ProcessInstanceInfoMatch {
public:
  ProcessInstanceInfoMatch() : m_match_info() {}

  ProcessInstanceInfoMatch(const char *process_name,
                           NameMatch process_name_match_type)
      : m_match_info(), m_name_match_type(process_name_match_type),
        m_match_all_users(false) {
    m_match_info.GetExecutableFile().SetFile(process_name,
                                             FileSpec::Style::native);
  }

  ProcessInstanceInfo &GetProcessInfo() { return m_match_info; }

  const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; }

  bool GetMatchAllUsers() const { return m_match_all_users; }

  void SetMatchAllUsers(bool b) { m_match_all_users = b; }

  NameMatch GetNameMatchType() const { return m_name_match_type; }

  void SetNameMatchType(NameMatch name_match_type) {
    m_name_match_type = name_match_type;
  }

  /// Return true iff the architecture in this object matches arch_spec.
  bool ArchitectureMatches(const ArchSpec &arch_spec) const;

  /// Return true iff the process name in this object matches process_name.
  bool NameMatches(const char *process_name) const;

  /// Return true iff the process ID and parent process IDs in this object match
  /// the ones in proc_info.
  bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const;

  /// Return true iff the (both effective and real) user and group IDs in this
  /// object match the ones in proc_info.
  bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const;

  bool Matches(const ProcessInstanceInfo &proc_info) const;

  bool MatchAllProcesses() const;
  void Clear();

protected:
  ProcessInstanceInfo m_match_info;
  NameMatch m_name_match_type = NameMatch::Ignore;
  bool m_match_all_users = false;
};

namespace repro {
llvm::Optional<ProcessInstanceInfoList> GetReplayProcessInstanceInfoList();
} // namespace repro
} // namespace lldb_private

LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ProcessInstanceInfo)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<lldb_private::ProcessInstanceInfo> {
  static void mapping(IO &io, lldb_private::ProcessInstanceInfo &PII);
};
} // namespace yaml
} // namespace llvm

#endif // LLDB_UTILITY_PROCESSINFO_H
