// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_THREAD_H_
#define SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_THREAD_H_

#include <lib/zx/exception.h>
#include <lib/zx/thread.h>
#include <zircon/syscalls/exception.h>

#include "src/developer/debug/debug_agent/arch.h"
#include "src/developer/debug/debug_agent/object_provider.h"
#include "src/developer/debug/ipc/protocol.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/ref_ptr.h"
#include "src/lib/fxl/memory/weak_ptr.h"

struct zx_thread_state_general_regs;

namespace debug_agent {

class DebugAgent;
class DebuggedProcess;
class ObjectProvider;
class ProcessBreakpoint;
class Watchpoint;

enum class ThreadCreationOption {
  // Already running, don't do anything
  kRunningKeepRunning,

  // Already suspended, keep it suspended
  kSuspendedKeepSuspended,

  // Already suspended, run it
  kSuspendedShouldRun
};

class DebuggedThread {
 public:
  // Represents a ref-counted suspend token to the debugged thread.
  // As long as one of these token is valid, the thread will maintain suspended.
  class SuspendToken {
   public:
    ~SuspendToken();

   private:
    SuspendToken(DebuggedThread*);

    fxl::WeakPtr<DebuggedThread> thread_;

    FXL_DISALLOW_COPY_ASSIGN_AND_MOVE(SuspendToken);
    friend class ::debug_agent::DebuggedThread;
  };

  // Represents the state the client thinks this thread is in. Certain
  // operations can suspend all the threads of a process and the debugger needs
  // to know which threads should remain suspended after that operation is done.
  enum class ClientState {
    kRunning,
    kPaused,
  };
  const char* ClientStateToString(ClientState);

  struct CreateInfo {
    DebuggedProcess* process = nullptr;
    zx_koid_t koid = 0;
    zx::thread handle;
    ThreadCreationOption creation_option = ThreadCreationOption::kRunningKeepRunning;

    std::unique_ptr<zx::exception> exception;  // Optional.

    std::shared_ptr<arch::ArchProvider> arch_provider;
    std::shared_ptr<ObjectProvider> object_provider;
  };
  DebuggedThread(DebugAgent*, CreateInfo&&);
  virtual ~DebuggedThread();

  const DebuggedProcess* process() const { return process_; }

  zx_koid_t koid() const { return koid_; }

  zx::thread& handle() { return handle_; }
  const zx::thread& handle() const { return handle_; }

  zx::exception* exception_handle() { return exception_handle_.get(); }
  const zx::exception* exception_handle() const { return exception_handle_.get(); }
  void set_exception_handle(std::unique_ptr<zx::exception> exception) {
    exception_handle_ = std::move(exception);
  }

  fxl::WeakPtr<DebuggedThread> GetWeakPtr();

  void OnException(std::unique_ptr<zx::exception> exception_handle,
                   zx_exception_info_t exception_info);

  // Resumes execution of the thread. The thread should currently be in a
  // stopped state. If it's not stopped, this will be ignored.
  void Resume(const debug_ipc::ResumeRequest& request);

  // Resumes the thread according to the current run mode.
  void ResumeForRunMode();

  // Resume the thread from an exception.
  // If |exception_handle_| is not valid, this will no-op.
  virtual void ResumeException();

  // Resume the thread from a suspension.
  // if |suspend_token_| is not valid, this will no-op.
  virtual void ResumeSuspension();

  // Pauses execution of the thread. Pausing happens asynchronously so the
  // thread will not necessarily have stopped when this returns. Set the
  // |synchronous| flag for blocking on the suspended signal and make this call
  // block until the thread is suspended.
  //
  // |new_state| represents what the new state of the client should be. If no
  // change is wanted, you can use the overload that doesn't receives that.
  //
  // Returns true if the thread was running at the moment of this call being
  // made. Returns false if it was on a suspension condition (suspended or on an
  // exception).
  virtual bool Suspend(bool synchronous = false);

  // Pauses execution of the thread. Pausing happens asynchronously so the thread will not
  // necessarily have stopped when this returns. Set the |synchronous| flag for blocking on the
  // suspended signal and make this call block.
  //
  // Suspension is ref-counted on the thread. This is done by returning a suspend token that will
  // keep track of how many suspensions this thread has. As long as there is a valid one, the
  // thread will remain suspended.
  [[nodiscard]] virtual std::unique_ptr<SuspendToken> RefCountedSuspend(bool synchronous = false);

  // The typical suspend deadline users should use when suspending.
  static zx::time DefaultSuspendDeadline();

  // Waits on a suspension token.
  // Returns true if we could find a valid suspension condition (either
  // suspended or on an exception). False if timeout or error.
  virtual bool WaitForSuspension(zx::time deadline = DefaultSuspendDeadline());

  // Fills the thread status record. If full_stack is set, a full backtrace
  // will be generated, otherwise a minimal one will be generated.
  //
  // If optional_regs is non-null, it should point to the current registers of
  // the thread. If null, these will be fetched automatically (this is an
  // optimization for cases where the caller has already requested registers).
  virtual void FillThreadRecord(debug_ipc::ThreadRecord::StackAmount stack_amount,
                                const zx_thread_state_general_regs* optional_regs,
                                debug_ipc::ThreadRecord* record) const;

  // Register reading and writing. The "write" command also has an output parameter which includes a
  // validated version of all registers re-read (and possibly others if they're known) from the
  // kernel after the write.
  void ReadRegisters(const std::vector<debug_ipc::RegisterCategory>& cats_to_get,
                     std::vector<debug_ipc::Register>* out) const;
  zx_status_t WriteRegisters(const std::vector<debug_ipc::Register>& regs,
                             std::vector<debug_ipc::Register>* written);

  // Sends a notification to the client about the state of this thread.
  void SendThreadNotification() const;

  // Notification that a ProcessBreakpoint is about to be deleted.
  void WillDeleteProcessBreakpoint(ProcessBreakpoint* bp);

  ClientState client_state() const { return client_state_; }
  void set_client_state(ClientState cs) { client_state_ = cs; }

  bool running() const { return !IsSuspended() && !IsInException(); }

  virtual bool IsSuspended() const { return ref_counted_suspend_token_.is_valid(); }
  virtual bool IsInException() const {
    return !!exception_handle_ && exception_handle_->is_valid();
  }

  int ref_counted_suspend_count() const { return suspend_count_; }

  bool stepping_over_breakpoint() const { return stepping_over_breakpoint_; }
  void set_stepping_over_breakpoint(bool so) { stepping_over_breakpoint_ = so; }

 protected:
  virtual void IncreaseSuspend();
  virtual void DecreaseSuspend();

  zx_koid_t koid_;
  zx::thread handle_;

 private:
  enum class OnStop {
    kIgnore,  // Don't do anything, keep the thread stopped and don't notify.
    kNotify,  // Send client notification like normal.
    kResume,  // The thread should be resumed from this exception.
  };

  void HandleSingleStep(debug_ipc::NotifyException*, zx_thread_state_general_regs*);
  void HandleGeneralException(debug_ipc::NotifyException*, zx_thread_state_general_regs*);
  void HandleSoftwareBreakpoint(debug_ipc::NotifyException*, zx_thread_state_general_regs*);
  void HandleHardwareBreakpoint(debug_ipc::NotifyException*, zx_thread_state_general_regs*);
  void HandleWatchpoint(debug_ipc::NotifyException*, zx_thread_state_general_regs*);

  void SendExceptionNotification(debug_ipc::NotifyException*, zx_thread_state_general_regs*);

  OnStop UpdateForSoftwareBreakpoint(zx_thread_state_general_regs* regs,
                                     std::vector<debug_ipc::BreakpointStats>* hit_breakpoints);

  // When hitting a SW breakpoint, the PC needs to be correctly re-set depending
  // on where the CPU leaves the PC after a SW exception.
  void FixSoftwareBreakpointAddress(ProcessBreakpoint* process_breakpoint,
                                    zx_thread_state_general_regs* regs);

  // Handles an exception corresponding to a ProcessBreakpoint. All
  // Breakpoints affected will have their updated stats added to
  // *hit_breakpoints.
  //
  // WARNING: The ProcessBreakpoint argument could be deleted in this call if it was a one-shot
  //          breakpoint, so it must not be used after this call.
  void UpdateForHitProcessBreakpoint(debug_ipc::BreakpointType exception_type,
                                     ProcessBreakpoint* process_breakpoint,
                                     zx_thread_state_general_regs* regs,
                                     std::vector<debug_ipc::BreakpointStats>* hit_breakpoints);

  // Sets or clears the single step bit on the thread.
  void SetSingleStep(bool single_step);

  DebugAgent* debug_agent_;   // Non-owning.
  DebuggedProcess* process_;  // Non-owning.

  // The main thing we're doing. When automatically resuming, this will be
  // what happens.
  debug_ipc::ResumeRequest::How run_mode_ = debug_ipc::ResumeRequest::How::kContinue;

  // When run_mode_ == kStepInRange, this defines the range (end non-inclusive).
  uint64_t step_in_range_begin_ = 0;
  uint64_t step_in_range_end_ = 0;

  // This is the state the client is considering this thread to be. This is used
  // for internal suspension the agent can do.
  ClientState client_state_ = ClientState::kRunning;

  int suspend_count_ = 0;
  // This permits users to simply call Suspend/Resume without having to worry about having to
  // track a suspend token. They could if they so wanted.
  std::unique_ptr<SuspendToken> local_suspend_token_;
  zx::suspend_token ref_counted_suspend_token_;

  // Active if the thread is currently on an exception.
  std::unique_ptr<zx::exception> exception_handle_;

  // Whether this thread is currently stepping over.
  bool stepping_over_breakpoint_ = false;

  // This can be set in two cases:
  // - When suspended after hitting a breakpoint, this will be the breakpoint
  //   that was hit.
  // - When single-stepping over a breakpoint, this will be the breakpoint
  //   being stepped over.
  ProcessBreakpoint* current_breakpoint_ = nullptr;

  std::shared_ptr<arch::ArchProvider> arch_provider_ = nullptr;
  std::shared_ptr<ObjectProvider> object_provider_ = nullptr;

  fxl::WeakPtrFactory<DebuggedThread> weak_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(DebuggedThread);

  friend class ::debug_agent::DebuggedThread::SuspendToken;
};

}  // namespace debug_agent

#endif  // SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_THREAD_H_
