//===-- ThreadList.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_ThreadList_h_
#define liblldb_ThreadList_h_

#include <mutex>
#include <vector>

#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadCollection.h"
#include "lldb/Utility/Iterable.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

// This is a thread list with lots of functionality for use only by the process
// for which this is the thread list.  A generic container class with iterator
// functionality is ThreadCollection.
class ThreadList : public ThreadCollection {
  friend class Process;

public:
  ThreadList(Process *process);

  ThreadList(const ThreadList &rhs);

  ~ThreadList() override;

  const ThreadList &operator=(const ThreadList &rhs);

  uint32_t GetSize(bool can_update = true);

  // Return the selected thread if there is one.  Otherwise, return the thread
  // selected at index 0.
  lldb::ThreadSP GetSelectedThread();

  // Manage the thread to use for running expressions.  This is usually the
  // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
  // & stop hooks) it isn't.
  class ExpressionExecutionThreadPusher {
  public:
    ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
        : m_thread_list(&thread_list), m_tid(tid) {
      m_thread_list->PushExpressionExecutionThread(m_tid);
    }

    ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);

    ~ExpressionExecutionThreadPusher() {
      if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
        m_thread_list->PopExpressionExecutionThread(m_tid);
    }

  private:
    ThreadList *m_thread_list;
    lldb::tid_t m_tid;
  };

  lldb::ThreadSP GetExpressionExecutionThread();

protected:
  void PushExpressionExecutionThread(lldb::tid_t tid);

  void PopExpressionExecutionThread(lldb::tid_t tid);

public:
  bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);

  bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);

  void Clear();

  void Flush();

  void Destroy();

  // Note that "idx" is not the same as the "thread_index". It is a zero based
  // index to accessing the current threads, whereas "thread_index" is a unique
  // index assigned
  lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);

  lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);

  lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid,
                                        bool can_update = true);

  lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);

  lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid,
                                          bool can_update = true);

  lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);

  lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);

  lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);

  bool ShouldStop(Event *event_ptr);

  Vote ShouldReportStop(Event *event_ptr);

  Vote ShouldReportRun(Event *event_ptr);

  void RefreshStateAfterStop();

  /// The thread list asks tells all the threads it is about to resume.
  /// If a thread can "resume" without having to resume the target, it
  /// will return false for WillResume, and then the process will not be
  /// restarted.
  ///
  /// \return
  ///    \b true instructs the process to resume normally,
  ///    \b false means start & stopped events will be generated, but
  ///    the process will not actually run.  The thread must then return
  ///    the correct StopInfo when asked.
  ///
  bool WillResume();

  void DidResume();

  void DidStop();

  void DiscardThreadPlans();

  uint32_t GetStopID() const;

  void SetStopID(uint32_t stop_id);

  std::recursive_mutex &GetMutex() const override;

  void Update(ThreadList &rhs);

protected:
  void SetShouldReportStop(Vote vote);

  void NotifySelectedThreadChanged(lldb::tid_t tid);

  // Classes that inherit from Process can see and modify these
  Process *m_process; ///< The process that manages this thread list.
  uint32_t
      m_stop_id; ///< The process stop ID that this thread list is valid for.
  lldb::tid_t
      m_selected_tid; ///< For targets that need the notion of a current thread.
  std::vector<lldb::tid_t> m_expression_tid_stack;

private:
  ThreadList() = delete;
};

} // namespace lldb_private

#endif // liblldb_ThreadList_h_
