//===-- 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/MipsLinuxSignals.h"
#include "Plugins/Process/Utility/NetBSDSignals.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Utility/ArchSpec.h"

using namespace lldb_private;

UnixSignals::Signal::Signal(const char *name, bool default_suppress,
                            bool default_stop, bool default_notify,
                            const char *description, const char *alias)
    : m_name(name), m_alias(alias), m_description(),
      m_suppress(default_suppress), m_stop(default_stop),
      m_notify(default_notify) {
  if (description)
    m_description.assign(description);
}

lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) {
  const auto &triple = arch.GetTriple();
  switch (triple.getOS()) {
  case llvm::Triple::Linux: {
    switch (triple.getArch()) {
    case llvm::Triple::mips:
    case llvm::Triple::mipsel:
    case llvm::Triple::mips64:
    case llvm::Triple::mips64el:
      return std::make_shared<MipsLinuxSignals>();
    default:
      return std::make_shared<LinuxSignals>();
    }
  }
  case llvm::Triple::FreeBSD:
  case llvm::Triple::OpenBSD:
    return std::make_shared<FreeBSDSignals>();
  case llvm::Triple::NetBSD:
    return std::make_shared<NetBSDSignals>();
  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, const char *name, bool default_suppress,
                            bool default_stop, bool default_notify,
                            const char *description, const char *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::RemoveSignal(int signo) {
  collection::iterator pos = m_signals.find(signo);
  if (pos != m_signals.end())
    m_signals.erase(pos);
  ++m_version;
}

const char *UnixSignals::GetSignalAsCString(int signo) const {
  collection::const_iterator pos = m_signals.find(signo);
  if (pos == m_signals.end())
    return nullptr;
  else
    return pos->second.m_name.GetCString();
}

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

ConstString UnixSignals::GetShortName(ConstString name) const {
  if (name)
    return ConstString(name.GetStringRef().substr(3)); // Remove "SIG" from name
  return name;
}

int32_t UnixSignals::GetSignalNumberFromName(const char *name) const {
  ConstString const_name(name);

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

  const int32_t signo =
      StringConvert::ToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0);
  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
    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;
  }
}

const char *UnixSignals::GetSignalInfo(int32_t signo, bool &should_suppress,
                                       bool &should_stop,
                                       bool &should_notify) const {
  collection::const_iterator pos = m_signals.find(signo);
  if (pos == m_signals.end())
    return nullptr;
  else {
    const Signal &signal = pos->second;
    should_suppress = signal.m_suppress;
    should_stop = signal.m_stop;
    should_notify = signal.m_notify;
    return signal.m_name.AsCString("");
  }
}

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(llvm::Optional<bool> should_suppress,
                                llvm::Optional<bool> should_stop,
                                llvm::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.hasValue() &&
        signal_suppress != should_suppress.getValue())
      continue;

    if (should_stop.hasValue() && signal_stop != should_stop.getValue())
      continue;

    if (should_notify.hasValue() && signal_notify != should_notify.getValue())
      continue;

    result.push_back(signo);
  }

  return result;
}
