//===-- UnixSignals.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 "lldb/Target/UnixSignals.h"
#include "Plugins/Process/Utility/FreeBSDSignals.h"
#include "Plugins/Process/Utility/LinuxSignals.h"
#include "Plugins/Process/Utility/NetBSDSignals.h"
#include "Plugins/Process/Utility/OpenBSDSignals.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include <optional>
#include <sstream>

using namespace lldb_private;
using namespace llvm;

UnixSignals::Signal::Signal(llvm::StringRef name, bool default_suppress,
                            bool default_stop, bool default_notify,
                            llvm::StringRef description, llvm::StringRef alias)
    : m_name(name), m_alias(alias), m_description(description),
      m_suppress(default_suppress), m_stop(default_stop),
      m_notify(default_notify), m_default_suppress(default_suppress),
      m_default_stop(default_stop), m_default_notify(default_notify) {}

lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) {
  const auto &triple = arch.GetTriple();
  switch (triple.getOS()) {
  case llvm::Triple::Linux:
    return std::make_shared<LinuxSignals>();
  case llvm::Triple::FreeBSD:
    return std::make_shared<FreeBSDSignals>();
  case llvm::Triple::NetBSD:
    return std::make_shared<NetBSDSignals>();
  case llvm::Triple::OpenBSD:
    return std::make_shared<OpenBSDSignals>();
  default:
    return std::make_shared<UnixSignals>();
  }
}

lldb::UnixSignalsSP UnixSignals::CreateForHost() {
  static lldb::UnixSignalsSP s_unix_signals_sp =
      Create(HostInfo::GetArchitecture());
  return s_unix_signals_sp;
}

// UnixSignals constructor
UnixSignals::UnixSignals() { Reset(); }

UnixSignals::UnixSignals(const UnixSignals &rhs) : m_signals(rhs.m_signals) {}

UnixSignals::~UnixSignals() = default;

void UnixSignals::Reset() {
  // This builds one standard set of Unix Signals. If yours aren't quite in
  // this order, you can either subclass this class, and use Add & Remove to
  // change them or you can subclass and build them afresh in your constructor.
  //
  // Note: the signals below are the Darwin signals. Do not change these!

  m_signals.clear();

  // clang-format off
  //        SIGNO   NAME            SUPPRESS  STOP    NOTIFY  DESCRIPTION
  //        ======  ==============  ========  ======  ======  ===================================================
  AddSignal(1,      "SIGHUP",       false,    true,   true,   "hangup");
  AddSignal(2,      "SIGINT",       true,     true,   true,   "interrupt");
  AddSignal(3,      "SIGQUIT",      false,    true,   true,   "quit");
  AddSignal(4,      "SIGILL",       false,    true,   true,   "illegal instruction");
  AddSignal(5,      "SIGTRAP",      true,     true,   true,   "trace trap (not reset when caught)");
  AddSignal(6,      "SIGABRT",      false,    true,   true,   "abort()");
  AddSignal(7,      "SIGEMT",       false,    true,   true,   "pollable event");
  AddSignal(8,      "SIGFPE",       false,    true,   true,   "floating point exception");
  AddSignal(9,      "SIGKILL",      false,    true,   true,   "kill");
  AddSignal(10,     "SIGBUS",       false,    true,   true,   "bus error");
  AddSignal(11,     "SIGSEGV",      false,    true,   true,   "segmentation violation");
  AddSignal(12,     "SIGSYS",       false,    true,   true,   "bad argument to system call");
  AddSignal(13,     "SIGPIPE",      false,    false,  false,  "write on a pipe with no one to read it");
  AddSignal(14,     "SIGALRM",      false,    false,  false,  "alarm clock");
  AddSignal(15,     "SIGTERM",      false,    true,   true,   "software termination signal from kill");
  AddSignal(16,     "SIGURG",       false,    false,  false,  "urgent condition on IO channel");
  AddSignal(17,     "SIGSTOP",      true,     true,   true,   "sendable stop signal not from tty");
  AddSignal(18,     "SIGTSTP",      false,    true,   true,   "stop signal from tty");
  AddSignal(19,     "SIGCONT",      false,    false,  true,   "continue a stopped process");
  AddSignal(20,     "SIGCHLD",      false,    false,  false,  "to parent on child stop or exit");
  AddSignal(21,     "SIGTTIN",      false,    true,   true,   "to readers process group upon background tty read");
  AddSignal(22,     "SIGTTOU",      false,    true,   true,   "to readers process group upon background tty write");
  AddSignal(23,     "SIGIO",        false,    false,  false,  "input/output possible signal");
  AddSignal(24,     "SIGXCPU",      false,    true,   true,   "exceeded CPU time limit");
  AddSignal(25,     "SIGXFSZ",      false,    true,   true,   "exceeded file size limit");
  AddSignal(26,     "SIGVTALRM",    false,    false,  false,  "virtual time alarm");
  AddSignal(27,     "SIGPROF",      false,    false,  false,  "profiling time alarm");
  AddSignal(28,     "SIGWINCH",     false,    false,  false,  "window size changes");
  AddSignal(29,     "SIGINFO",      false,    true,   true,   "information request");
  AddSignal(30,     "SIGUSR1",      false,    true,   true,   "user defined signal 1");
  AddSignal(31,     "SIGUSR2",      false,    true,   true,   "user defined signal 2");
  // clang-format on
}

void UnixSignals::AddSignal(int signo, llvm::StringRef name,
                            bool default_suppress, bool default_stop,
                            bool default_notify, llvm::StringRef description,
                            llvm::StringRef alias) {
  Signal new_signal(name, default_suppress, default_stop, default_notify,
                    description, alias);
  m_signals.insert(std::make_pair(signo, new_signal));
  ++m_version;
}

void UnixSignals::AddSignalCode(int signo, int code,
                                const llvm::StringLiteral description,
                                SignalCodePrintOption print_option) {
  collection::iterator signal = m_signals.find(signo);
  assert(signal != m_signals.end() &&
         "Tried to add code to signal that does not exist.");
  signal->second.m_codes.insert(
      std::pair{code, SignalCode{description, print_option}});
  ++m_version;
}

void UnixSignals::RemoveSignal(int signo) {
  collection::iterator pos = m_signals.find(signo);
  if (pos != m_signals.end())
    m_signals.erase(pos);
  ++m_version;
}

llvm::StringRef UnixSignals::GetSignalAsStringRef(int32_t signo) const {
  const auto pos = m_signals.find(signo);
  if (pos == m_signals.end())
    return {};
  return pos->second.m_name;
}

llvm::StringRef UnixSignals::GetSignalNumberDescription(int32_t signo) const {
  const auto pos = m_signals.find(signo);
  if (pos == m_signals.end())
    return {};
  return pos->second.m_description;
}

std::string UnixSignals::GetSignalDescription(
    int32_t signo, std::optional<int32_t> code,
    std::optional<lldb::addr_t> addr, std::optional<lldb::addr_t> lower,
    std::optional<lldb::addr_t> upper, std::optional<uint32_t> pid,
    std::optional<uint32_t> uid) const {
  std::string str;

  collection::const_iterator pos = m_signals.find(signo);
  if (pos != m_signals.end()) {
    str = pos->second.m_name.str();

    if (code) {
      std::map<int32_t, SignalCode>::const_iterator cpos =
          pos->second.m_codes.find(*code);
      if (cpos != pos->second.m_codes.end()) {
        const SignalCode &sc = cpos->second;
        str += ": ";
        if (sc.m_print_option != SignalCodePrintOption::Bounds)
          str += sc.m_description.str();

        std::stringstream strm;
        switch (sc.m_print_option) {
        case SignalCodePrintOption::None:
          break;
        case SignalCodePrintOption::Address:
          if (addr)
            strm << " (fault address=0x" << std::hex << *addr << ")";
          break;
        case SignalCodePrintOption::Bounds:
          if (lower && upper && addr) {
            if ((unsigned long)(*addr) < *lower)
              strm << "lower bound violation ";
            else
              strm << "upper bound violation ";

            strm << "(fault address=0x" << std::hex << *addr;
            strm << ", lower bound=0x" << std::hex << *lower;
            strm << ", upper bound=0x" << std::hex << *upper;
            strm << ")";
          } else
            strm << sc.m_description.str();

          break;
        case SignalCodePrintOption::Sender:
          if (pid && uid)
            strm << " (sender pid=" << *pid << ", uid=" << *uid << ")";
          break;
        }
        str += strm.str();
      }
    }
  }

  return str;
}

bool UnixSignals::SignalIsValid(int32_t signo) const {
  return m_signals.find(signo) != m_signals.end();
}

llvm::StringRef UnixSignals::GetShortName(llvm::StringRef name) const {
  return name.substr(3); // Remove "SIG" from name
}

int32_t UnixSignals::GetSignalNumberFromName(const char *name) const {
  llvm::StringRef name_ref(name);

  collection::const_iterator pos, end = m_signals.end();
  for (pos = m_signals.begin(); pos != end; pos++) {
    if ((name_ref == pos->second.m_name) || (name_ref == pos->second.m_alias) ||
        (name_ref == GetShortName(pos->second.m_name)) ||
        (name_ref == GetShortName(pos->second.m_alias)))
      return pos->first;
  }

  int32_t signo;
  if (llvm::to_integer(name, signo))
    return signo;
  return LLDB_INVALID_SIGNAL_NUMBER;
}

int32_t UnixSignals::GetFirstSignalNumber() const {
  if (m_signals.empty())
    return LLDB_INVALID_SIGNAL_NUMBER;

  return (*m_signals.begin()).first;
}

int32_t UnixSignals::GetNextSignalNumber(int32_t current_signal) const {
  collection::const_iterator pos = m_signals.find(current_signal);
  collection::const_iterator end = m_signals.end();
  if (pos == end)
    return LLDB_INVALID_SIGNAL_NUMBER;
  else {
    pos++;
    if (pos == end)
      return LLDB_INVALID_SIGNAL_NUMBER;
    else
      return pos->first;
  }
}

bool UnixSignals::GetSignalInfo(int32_t signo, bool &should_suppress,
                                bool &should_stop, bool &should_notify) const {
  const auto pos = m_signals.find(signo);
  if (pos == m_signals.end())
    return false;

  const Signal &signal = pos->second;
  should_suppress = signal.m_suppress;
  should_stop = signal.m_stop;
  should_notify = signal.m_notify;
  return true;
}

bool UnixSignals::GetShouldSuppress(int signo) const {
  collection::const_iterator pos = m_signals.find(signo);
  if (pos != m_signals.end())
    return pos->second.m_suppress;
  return false;
}

bool UnixSignals::SetShouldSuppress(int signo, bool value) {
  collection::iterator pos = m_signals.find(signo);
  if (pos != m_signals.end()) {
    pos->second.m_suppress = value;
    ++m_version;
    return true;
  }
  return false;
}

bool UnixSignals::SetShouldSuppress(const char *signal_name, bool value) {
  const int32_t signo = GetSignalNumberFromName(signal_name);
  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
    return SetShouldSuppress(signo, value);
  return false;
}

bool UnixSignals::GetShouldStop(int signo) const {
  collection::const_iterator pos = m_signals.find(signo);
  if (pos != m_signals.end())
    return pos->second.m_stop;
  return false;
}

bool UnixSignals::SetShouldStop(int signo, bool value) {
  collection::iterator pos = m_signals.find(signo);
  if (pos != m_signals.end()) {
    pos->second.m_stop = value;
    ++m_version;
    return true;
  }
  return false;
}

bool UnixSignals::SetShouldStop(const char *signal_name, bool value) {
  const int32_t signo = GetSignalNumberFromName(signal_name);
  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
    return SetShouldStop(signo, value);
  return false;
}

bool UnixSignals::GetShouldNotify(int signo) const {
  collection::const_iterator pos = m_signals.find(signo);
  if (pos != m_signals.end())
    return pos->second.m_notify;
  return false;
}

bool UnixSignals::SetShouldNotify(int signo, bool value) {
  collection::iterator pos = m_signals.find(signo);
  if (pos != m_signals.end()) {
    pos->second.m_notify = value;
    ++m_version;
    return true;
  }
  return false;
}

bool UnixSignals::SetShouldNotify(const char *signal_name, bool value) {
  const int32_t signo = GetSignalNumberFromName(signal_name);
  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
    return SetShouldNotify(signo, value);
  return false;
}

int32_t UnixSignals::GetNumSignals() const { return m_signals.size(); }

int32_t UnixSignals::GetSignalAtIndex(int32_t index) const {
  if (index < 0 || m_signals.size() <= static_cast<size_t>(index))
    return LLDB_INVALID_SIGNAL_NUMBER;
  auto it = m_signals.begin();
  std::advance(it, index);
  return it->first;
}

uint64_t UnixSignals::GetVersion() const { return m_version; }

std::vector<int32_t>
UnixSignals::GetFilteredSignals(std::optional<bool> should_suppress,
                                std::optional<bool> should_stop,
                                std::optional<bool> should_notify) {
  std::vector<int32_t> result;
  for (int32_t signo = GetFirstSignalNumber();
       signo != LLDB_INVALID_SIGNAL_NUMBER;
       signo = GetNextSignalNumber(signo)) {

    bool signal_suppress = false;
    bool signal_stop = false;
    bool signal_notify = false;
    GetSignalInfo(signo, signal_suppress, signal_stop, signal_notify);

    // If any of filtering conditions are not met, we move on to the next
    // signal.
    if (should_suppress && signal_suppress != *should_suppress)
      continue;

    if (should_stop && signal_stop != *should_stop)
      continue;

    if (should_notify && signal_notify != *should_notify)
      continue;

    result.push_back(signo);
  }

  return result;
}

void UnixSignals::IncrementSignalHitCount(int signo) {
  collection::iterator pos = m_signals.find(signo);
  if (pos != m_signals.end())
    pos->second.m_hit_count += 1;
}

json::Value UnixSignals::GetHitCountStatistics() const {
  json::Array json_signals;
  for (const auto &pair : m_signals) {
    if (pair.second.m_hit_count > 0)
      json_signals.emplace_back(
          json::Object{{pair.second.m_name, pair.second.m_hit_count}});
  }
  return std::move(json_signals);
}

void UnixSignals::Signal::Reset(bool reset_stop, bool reset_notify, 
                                bool reset_suppress) {
  if (reset_stop)
    m_stop = m_default_stop;
  if (reset_notify)
    m_notify = m_default_notify;
  if (reset_suppress)
    m_suppress = m_default_suppress;
}

bool UnixSignals::ResetSignal(int32_t signo, bool reset_stop, 
                                 bool reset_notify, bool reset_suppress) {
    auto elem = m_signals.find(signo);
    if (elem == m_signals.end())
      return false;
    (*elem).second.Reset(reset_stop, reset_notify, reset_suppress);
    return true;
}
