//===-- Debug.h -------------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Debug_h_
#define liblldb_Debug_h_

#include <vector>

#include "lldb/lldb-private.h"

namespace lldb_private {

// Tells a thread what it needs to do when the process is resumed.
struct ResumeAction {
  lldb::tid_t tid;       // The thread ID that this action applies to,
                         // LLDB_INVALID_THREAD_ID for the default thread
                         // action
  lldb::StateType state; // Valid values are eStateStopped/eStateSuspended,
                         // eStateRunning, and eStateStepping.
  int signal; // When resuming this thread, resume it with this signal if this
              // value is > 0
};

// A class that contains instructions for all threads for
// NativeProcessProtocol::Resume(). Each thread can either run, stay suspended,
// or step when the process is resumed. We optionally have the ability to also
// send a signal to the thread when the action is run or step.
class ResumeActionList {
public:
  ResumeActionList() : m_actions(), m_signal_handled() {}

  ResumeActionList(lldb::StateType default_action, int signal)
      : m_actions(), m_signal_handled() {
    SetDefaultThreadActionIfNeeded(default_action, signal);
  }

  ResumeActionList(const ResumeAction *actions, size_t num_actions)
      : m_actions(), m_signal_handled() {
    if (actions && num_actions) {
      m_actions.assign(actions, actions + num_actions);
      m_signal_handled.assign(num_actions, false);
    }
  }

  ~ResumeActionList() = default;

  bool IsEmpty() const { return m_actions.empty(); }

  void Append(const ResumeAction &action) {
    m_actions.push_back(action);
    m_signal_handled.push_back(false);
  }

  void AppendAction(lldb::tid_t tid, lldb::StateType state, int signal = 0) {
    ResumeAction action = {tid, state, signal};
    Append(action);
  }

  void AppendResumeAll() {
    AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateRunning);
  }

  void AppendSuspendAll() {
    AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStopped);
  }

  void AppendStepAll() {
    AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStepping);
  }

  const ResumeAction *GetActionForThread(lldb::tid_t tid,
                                         bool default_ok) const {
    const size_t num_actions = m_actions.size();
    for (size_t i = 0; i < num_actions; ++i) {
      if (m_actions[i].tid == tid)
        return &m_actions[i];
    }
    if (default_ok && tid != LLDB_INVALID_THREAD_ID)
      return GetActionForThread(LLDB_INVALID_THREAD_ID, false);
    return nullptr;
  }

  size_t NumActionsWithState(lldb::StateType state) const {
    size_t count = 0;
    const size_t num_actions = m_actions.size();
    for (size_t i = 0; i < num_actions; ++i) {
      if (m_actions[i].state == state)
        ++count;
    }
    return count;
  }

  bool SetDefaultThreadActionIfNeeded(lldb::StateType action, int signal) {
    if (GetActionForThread(LLDB_INVALID_THREAD_ID, true) == nullptr) {
      // There isn't a default action so we do need to set it.
      ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal};
      m_actions.push_back(default_action);
      m_signal_handled.push_back(false);
      return true; // Return true as we did add the default action
    }
    return false;
  }

  void SetSignalHandledForThread(lldb::tid_t tid) const {
    if (tid != LLDB_INVALID_THREAD_ID) {
      const size_t num_actions = m_actions.size();
      for (size_t i = 0; i < num_actions; ++i) {
        if (m_actions[i].tid == tid)
          m_signal_handled[i] = true;
      }
    }
  }

  const ResumeAction *GetFirst() const { return m_actions.data(); }

  size_t GetSize() const { return m_actions.size(); }

  void Clear() {
    m_actions.clear();
    m_signal_handled.clear();
  }

protected:
  std::vector<ResumeAction> m_actions;
  mutable std::vector<bool> m_signal_handled;
};

struct ThreadStopInfo {
  lldb::StopReason reason;
  union {
    // eStopReasonSignal
    struct {
      uint32_t signo;
    } signal;

    // eStopReasonException
    struct {
      uint64_t type;
      uint32_t data_count;
      lldb::addr_t data[8];
    } exception;
  } details;
};
}

#endif // liblldb_Debug_h_
