//===-- ThreadMemory.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_ThreadMemory_h_
#define liblldb_ThreadMemory_h_

// C Includes
// C++ Includes
#include <string>

// Other libraries and framework includes
// Project includes
#include "lldb/Target/Thread.h"

class ThreadMemory : public lldb_private::Thread {
public:
  ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
               const lldb::ValueObjectSP &thread_info_valobj_sp);

  ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
               const char *name, const char *queue,
               lldb::addr_t register_data_addr);

  ~ThreadMemory() override;

  lldb::RegisterContextSP GetRegisterContext() override;

  lldb::RegisterContextSP
  CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;

  bool CalculateStopInfo() override;

  const char *GetInfo() override {
    if (m_backing_thread_sp)
      m_backing_thread_sp->GetInfo();
    return nullptr;
  }

  const char *GetName() override {
    if (!m_name.empty())
      return m_name.c_str();
    if (m_backing_thread_sp)
      m_backing_thread_sp->GetName();
    return nullptr;
  }

  const char *GetQueueName() override {
    if (!m_queue.empty())
      return m_queue.c_str();
    if (m_backing_thread_sp)
      m_backing_thread_sp->GetQueueName();
    return nullptr;
  }

  void WillResume(lldb::StateType resume_state) override;

  void DidResume() override {
    if (m_backing_thread_sp)
      m_backing_thread_sp->DidResume();
  }

  lldb::user_id_t GetProtocolID() const override {
    if (m_backing_thread_sp)
      return m_backing_thread_sp->GetProtocolID();
    return Thread::GetProtocolID();
  }

  void RefreshStateAfterStop() override;

  lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; }

  void ClearStackFrames() override;

  void ClearBackingThread() override { m_backing_thread_sp.reset(); }

  bool SetBackingThread(const lldb::ThreadSP &thread_sp) override {
    // printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(),
    // thread_sp->GetID());
    m_backing_thread_sp = thread_sp;
    return (bool)thread_sp;
  }

  lldb::ThreadSP GetBackingThread() const override {
    return m_backing_thread_sp;
  }

protected:
  bool IsOperatingSystemPluginThread() const override { return true; }

  // If this memory thread is actually represented by a thread from the
  // lldb_private::Process subclass, then fill in the thread here and
  // all APIs will be routed through this thread object. If m_backing_thread_sp
  // is empty, then this thread is simply in memory with no representation
  // through the process plug-in.
  lldb::ThreadSP m_backing_thread_sp;
  lldb::ValueObjectSP m_thread_info_valobj_sp;
  std::string m_name;
  std::string m_queue;
  lldb::addr_t m_register_data_addr;

private:
  DISALLOW_COPY_AND_ASSIGN(ThreadMemory);
};

#endif // liblldb_ThreadMemory_h_
