//===-- UnixSignals.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/UnixSignals.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/StringConvert.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"

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>();
    }
}

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

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

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
UnixSignals::~UnixSignals ()
{
}

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;
    m_signals.clear();
    //        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,   true , true , "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,   true , 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");
}

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));
}

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

const char *
UnixSignals::GetSignalAsCString (int signo) const
{
    collection::const_iterator pos = m_signals.find (signo);
    if (pos == m_signals.end())
        return NULL;
    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)
    {
      char* signame = (char*)(name.AsCString());
      return ConstString(signame + 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 NULL;
    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;
        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;
        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;
        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;
}
