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

#ifndef liblldb_ProcessMessage_H_
#define liblldb_ProcessMessage_H_

#include "CrashReason.h"

#include <cassert>
#include <string>

#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"

class ProcessMessage
{
public:

    /// The type of signal this message can correspond to.
    enum Kind
    {
        eInvalidMessage,
        eAttachMessage,
        eExitMessage,
        eLimboMessage,
        eSignalMessage,
        eSignalDeliveredMessage,
        eTraceMessage,
        eBreakpointMessage,
        eWatchpointMessage,
        eCrashMessage,
        eNewThreadMessage,
        eExecMessage
    };

    ProcessMessage()
        : m_tid(LLDB_INVALID_PROCESS_ID),
          m_kind(eInvalidMessage),
          m_crash_reason(CrashReason::eInvalidCrashReason),
          m_status(0),
          m_addr(0) { }

    Kind GetKind() const { return m_kind; }

    lldb::tid_t GetTID() const { return m_tid; }

    /// Indicates that the process @p pid has successfully attached.
    static ProcessMessage Attach(lldb::pid_t pid) {
        return ProcessMessage(pid, eAttachMessage);
    }

    /// Indicates that the thread @p tid is about to exit with status @p status.
    static ProcessMessage Limbo(lldb::tid_t tid, int status) {
        return ProcessMessage(tid, eLimboMessage, status);
    }

    /// Indicates that the thread @p tid had the signal @p signum delivered.
    static ProcessMessage Signal(lldb::tid_t tid, int signum) {
        return ProcessMessage(tid, eSignalMessage, signum);
    }

    /// Indicates that a signal @p signum generated by the debugging process was
    /// delivered to the thread @p tid.
    static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
        return ProcessMessage(tid, eSignalDeliveredMessage, signum);
    }

    /// Indicates that the thread @p tid encountered a trace point.
    static ProcessMessage Trace(lldb::tid_t tid) {
        return ProcessMessage(tid, eTraceMessage);
    }

    /// Indicates that the thread @p tid encountered a break point.
    static ProcessMessage Break(lldb::tid_t tid) {
        return ProcessMessage(tid, eBreakpointMessage);
    }

    static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
        return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
    }

    /// Indicates that the thread @p tid crashed.
    static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
                                int signo, lldb::addr_t fault_addr) {
        ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
        message.m_crash_reason = reason;
        return message;
    }

    /// Indicates that the thread @p child_tid was spawned.
    static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
        return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
    }

    /// Indicates that the thread @p tid is about to exit with status @p status.
    static ProcessMessage Exit(lldb::tid_t tid, int status) {
        return ProcessMessage(tid, eExitMessage, status);
    }

    /// Indicates that the thread @p pid has exec'd.
    static ProcessMessage Exec(lldb::tid_t tid) {
        return ProcessMessage(tid, eExecMessage);
    }

    int GetExitStatus() const {
        assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
        return m_status;
    }

    int GetSignal() const {
        assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
               GetKind() == eSignalDeliveredMessage);
        return m_status;
    }

    int GetStopStatus() const {
        assert(GetKind() == eSignalMessage);
        return m_status;
    }

    CrashReason GetCrashReason() const {
        assert(GetKind() == eCrashMessage);
        return m_crash_reason;
    }

    lldb::addr_t GetFaultAddress() const {
        assert(GetKind() == eCrashMessage);
        return m_addr;
    }

    lldb::addr_t GetHWAddress() const {
        assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
        return m_addr;
    }

    lldb::tid_t GetChildTID() const {
        assert(GetKind() == eNewThreadMessage);
        return m_child_tid;
    }

    const char *
    PrintCrashReason() const;

    const char *
    PrintKind() const;

    static const char *
    PrintKind(Kind);

private:
    ProcessMessage(lldb::tid_t tid, Kind kind, 
                   int status = 0, lldb::addr_t addr = 0)
        : m_tid(tid),
          m_kind(kind),
          m_crash_reason(CrashReason::eInvalidCrashReason),
          m_status(status),
          m_addr(addr),
          m_child_tid(0) { }

    ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
        : m_tid(tid),
          m_kind(kind),
          m_crash_reason(CrashReason::eInvalidCrashReason),
          m_status(0),
          m_addr(0),
          m_child_tid(child_tid) { }

    lldb::tid_t m_tid;
    Kind        m_kind         : 8;
    CrashReason m_crash_reason;
    int m_status;
    lldb::addr_t m_addr;
    lldb::tid_t m_child_tid;
};

#endif // #ifndef liblldb_ProcessMessage_H_
