//===-- MachThread.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
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/19/07.
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H
#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_MACHTHREAD_H

#include <mutex>
#include <string>
#include <vector>

#include <libproc.h>
#include <mach/mach.h>
#include <pthread.h>
#include <sys/signal.h>

#include "DNBArch.h"
#include "DNBRegisterInfo.h"
#include "MachException.h"

#include "ThreadInfo.h"

class DNBBreakpoint;
class MachProcess;
class MachThreadList;

class MachThread {
public:
  MachThread(MachProcess *process, bool is_64_bit,
             uint64_t unique_thread_id = 0, thread_t mach_port_number = 0);
  ~MachThread();

  MachProcess *Process() { return m_process; }
  const MachProcess *Process() const { return m_process; }
  nub_process_t ProcessID() const;
  void Dump(uint32_t index);
  uint64_t ThreadID() const { return m_unique_id; }
  thread_t MachPortNumber() const { return m_mach_port_number; }
  thread_t InferiorThreadID() const;

  uint32_t SequenceID() const { return m_seq_id; }
  static bool ThreadIDIsValid(
      uint64_t thread); // The 64-bit system-wide unique thread identifier
  static bool MachPortNumberIsValid(thread_t thread); // The mach port # for
                                                      // this thread in
                                                      // debugserver namespace
  void Resume(bool others_stopped);
  void Suspend();
  bool SetSuspendCountBeforeResume(bool others_stopped);
  bool RestoreSuspendCountAfterStop();

  bool GetRegisterState(int flavor, bool force);
  bool SetRegisterState(int flavor);
  uint64_t
  GetPC(uint64_t failValue = INVALID_NUB_ADDRESS); // Get program counter
  bool SetPC(uint64_t value);                      // Set program counter
  uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer

  DNBBreakpoint *CurrentBreakpoint();
  uint32_t EnableHardwareBreakpoint(const DNBBreakpoint *breakpoint,
                                    bool also_set_on_task);
  uint32_t EnableHardwareWatchpoint(const DNBBreakpoint *watchpoint,
                                    bool also_set_on_task);
  bool DisableHardwareBreakpoint(const DNBBreakpoint *breakpoint,
                                 bool also_set_on_task);
  bool DisableHardwareWatchpoint(const DNBBreakpoint *watchpoint,
                                 bool also_set_on_task);
  uint32_t NumSupportedHardwareWatchpoints() const;
  bool RollbackTransForHWP();
  bool FinishTransForHWP();

  nub_state_t GetState();
  void SetState(nub_state_t state);

  void ThreadWillResume(const DNBThreadResumeAction *thread_action,
                        bool others_stopped = false);
  bool ShouldStop(bool &step_more);
  bool IsStepping();
  bool ThreadDidStop();
  bool NotifyException(MachException::Data &exc);
  const MachException::Data &GetStopException() { return m_stop_exception; }

  nub_size_t GetNumRegistersInSet(nub_size_t regSet) const;
  const char *GetRegisterSetName(nub_size_t regSet) const;
  const DNBRegisterInfo *GetRegisterInfo(nub_size_t regSet,
                                         nub_size_t regIndex) const;
  void DumpRegisterState(nub_size_t regSet);
  const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets) const;
  bool GetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx,
                        DNBRegisterValue *reg_value);
  bool SetRegisterValue(uint32_t reg_set_idx, uint32_t reg_idx,
                        const DNBRegisterValue *reg_value);
  nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len);
  nub_size_t SetRegisterContext(const void *buf, nub_size_t buf_len);
  uint32_t SaveRegisterState();
  bool RestoreRegisterState(uint32_t save_id);

  void NotifyBreakpointChanged(const DNBBreakpoint *bp) {}

  bool IsUserReady();
  struct thread_basic_info *GetBasicInfo();
  struct thread_extended_info *GetExtendedInfo();
  const char *GetBasicInfoAsString() const;
  const char *GetName();

  DNBArchProtocol *GetArchProtocol() { return m_arch_up.get(); }

  ThreadInfo::QoS GetRequestedQoS(nub_addr_t tsd, uint64_t dti_qos_class_index);
  nub_addr_t GetPThreadT();
  nub_addr_t GetDispatchQueueT();
  nub_addr_t
  GetTSDAddressForThread(uint64_t plo_pthread_tsd_base_address_offset,
                         uint64_t plo_pthread_tsd_base_offset,
                         uint64_t plo_pthread_tsd_entry_size);

  static uint64_t GetGloballyUniqueThreadIDForMachPortID(thread_t mach_port_id);

protected:
  static bool GetBasicInfo(thread_t threadID,
                           struct thread_basic_info *basic_info);
  static bool GetExtendedInfo(thread_t threadID,
                              struct thread_extended_info *extended_info);

  //    const char *
  //    GetDispatchQueueName();
  //
  MachProcess *m_process; // The process that owns this thread
  uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t)
  thread_t m_mach_port_number; // The mach port # for this thread in debugserver
                               // namesp.
  uint32_t m_seq_id;   // A Sequential ID that increments with each new thread
  nub_state_t m_state; // The state of our process
  std::recursive_mutex m_state_mutex;    // Multithreaded protection for m_state
  struct thread_basic_info m_basic_info; // Basic information for a thread used
                                         // to see if a thread is valid
  int32_t m_suspend_count; // The current suspend count > 0 means we have
                           // suspended m_suspendCount times,
  //                           < 0 means we have resumed it m_suspendCount
  //                           times.
  MachException::Data m_stop_exception; // The best exception that describes why
                                        // this thread is stopped
  std::unique_ptr<DNBArchProtocol>
      m_arch_up; // Arch specific information for register state and more
  const DNBRegisterSetInfo
      *m_reg_sets; // Register set information for this thread
  nub_size_t m_num_reg_sets;
  thread_extended_info_data_t m_extended_info;
  std::string m_dispatch_queue_name;
  bool m_is_64_bit;

  // qos_class_t _pthread_qos_class_decode(pthread_priority_t priority, int *,
  // unsigned long *);
  unsigned int (*m_pthread_qos_class_decode)(unsigned long priority, int *,
                                             unsigned long *);

private:
  friend class MachThreadList;
};

typedef std::shared_ptr<MachThread> MachThreadSP;

#endif
