//===-- source/Host/openbsd/Host.cpp --------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include <sys/types.h>

#include <sys/signal.h>
#include <sys/exec.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/sysctl.h>
#include <sys/user.h>

#include <cstdio>

#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/NameMatches.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"

#include "llvm/Support/Host.h"

extern "C" {
extern char **environ;
}

using namespace lldb;
using namespace lldb_private;

namespace lldb_private {
class ProcessLaunchInfo;
}

Environment Host::GetEnvironment() {
  Environment env;
  char *v;
  char **var = environ;
  for (; var != NULL && *var != NULL; ++var) {
    v = strchr(*var, (int)'-');
    if (v == NULL)
      continue;
    env.insert(v);
  }
  return env;
}

static bool
GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
                      ProcessInstanceInfo &process_info) {
  if (process_info.ProcessIDIsValid()) {
    int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS,
                  (int)process_info.GetProcessID()};

    char arg_data[8192];
    size_t arg_data_size = sizeof(arg_data);
    if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) {
      DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(),
                         sizeof(void *));
      lldb::offset_t offset = 0;
      const char *cstr;

      cstr = data.GetCStr(&offset);
      if (cstr) {
        process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native);

        if (!(match_info_ptr == NULL ||
              NameMatches(
                  process_info.GetExecutableFile().GetFilename().GetCString(),
                  match_info_ptr->GetNameMatchType(),
                  match_info_ptr->GetProcessInfo().GetName())))
          return false;

        Args &proc_args = process_info.GetArguments();
        while (1) {
          const uint8_t *p = data.PeekData(offset, 1);
          while ((p != NULL) && (*p == '\0') && offset < arg_data_size) {
            ++offset;
            p = data.PeekData(offset, 1);
          }
          if (p == NULL || offset >= arg_data_size)
            return true;

          cstr = data.GetCStr(&offset);
          if (cstr)
            proc_args.AppendArgument(llvm::StringRef(cstr));
          else
            return true;
        }
      }
    }
  }
  return false;
}

static bool GetOpenBSDProcessCPUType(ProcessInstanceInfo &process_info) {
  if (process_info.ProcessIDIsValid()) {
    process_info.GetArchitecture() =
        HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
    return true;
  }
  process_info.GetArchitecture().Clear();
  return false;
}

static bool GetOpenBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) {
  struct kinfo_proc proc_kinfo;
  size_t proc_kinfo_size;

  if (process_info.ProcessIDIsValid()) {
    int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
                  (int)process_info.GetProcessID()};
    proc_kinfo_size = sizeof(struct kinfo_proc);

    if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
      if (proc_kinfo_size > 0) {
        process_info.SetParentProcessID(proc_kinfo.p_ppid);
        process_info.SetUserID(proc_kinfo.p_ruid);
        process_info.SetGroupID(proc_kinfo.p_rgid);
        process_info.SetEffectiveUserID(proc_kinfo.p_uid);
	process_info.SetEffectiveGroupID(proc_kinfo.p_gid);
        return true;
      }
    }
  }
  process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID);
  process_info.SetUserID(UINT32_MAX);
  process_info.SetGroupID(UINT32_MAX);
  process_info.SetEffectiveUserID(UINT32_MAX);
  process_info.SetEffectiveGroupID(UINT32_MAX);
  return false;
}

uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
                                 ProcessInstanceInfoList &process_infos) {
  std::vector<struct kinfo_proc> kinfos;

  int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};

  size_t pid_data_size = 0;
  if (::sysctl(mib, 3, NULL, &pid_data_size, NULL, 0) != 0)
    return 0;

  // Add a few extra in case a few more show up
  const size_t estimated_pid_count =
      (pid_data_size / sizeof(struct kinfo_proc)) + 10;

  kinfos.resize(estimated_pid_count);
  pid_data_size = kinfos.size() * sizeof(struct kinfo_proc);

  if (::sysctl(mib, 3, &kinfos[0], &pid_data_size, NULL, 0) != 0)
    return 0;

  const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));

  bool all_users = match_info.GetMatchAllUsers();
  const ::pid_t our_pid = getpid();
  const uid_t our_uid = getuid();
  for (size_t i = 0; i < actual_pid_count; i++) {
    const struct kinfo_proc &kinfo = kinfos[i];
    const bool kinfo_user_matches = (all_users || (kinfo.p_ruid == our_uid) ||
                                     // Special case, if lldb is being run as
                                     // root we can attach to anything.
                                     (our_uid == 0));

    if (kinfo_user_matches == false || // Make sure the user is acceptable
        kinfo.p_pid == our_pid ||     // Skip this process
        kinfo.p_pid == 0 ||           // Skip kernel (kernel pid is zero)
        kinfo.p_stat == SZOMB ||      // Zombies are bad, they like brains...
        kinfo.p_psflags & PS_TRACED || // Being debugged?
        kinfo.p_flag & P_WEXIT)       // Working on exiting
      continue;

    ProcessInstanceInfo process_info;
    process_info.SetProcessID(kinfo.p_pid);
    process_info.SetParentProcessID(kinfo.p_ppid);
    process_info.SetUserID(kinfo.p_ruid);
    process_info.SetGroupID(kinfo.p_rgid);
    process_info.SetEffectiveUserID(kinfo.p_svuid);
    process_info.SetEffectiveGroupID(kinfo.p_svgid);

    // Make sure our info matches before we go fetch the name and cpu type
    if (match_info.Matches(process_info) &&
        GetOpenBSDProcessArgs(&match_info, process_info)) {
      GetOpenBSDProcessCPUType(process_info);
      if (match_info.Matches(process_info))
        process_infos.push_back(process_info);
    }
  }

  return process_infos.size();
}

bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
  process_info.SetProcessID(pid);

  if (GetOpenBSDProcessArgs(NULL, process_info)) {
    // should use libprocstat instead of going right into sysctl?
    GetOpenBSDProcessCPUType(process_info);
    GetOpenBSDProcessUserAndGroup(process_info);
    return true;
  }

  process_info.Clear();
  return false;
}

Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
  return Status("unimplemented");
}
