//===-- ThreadMemory.cpp ----------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Plugins/Process/Utility/ThreadMemory.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Unwind.h"
#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"

using namespace lldb;
using namespace lldb_private;

ThreadMemory::ThreadMemory (Process &process,
                            tid_t tid,
                            const ValueObjectSP &thread_info_valobj_sp) :
    Thread (process, tid),
    m_backing_thread_sp (),
    m_thread_info_valobj_sp (thread_info_valobj_sp),
    m_name(),
    m_queue()
{
}


ThreadMemory::ThreadMemory (Process &process,
                            lldb::tid_t tid,
                            const char *name,
                            const char *queue,
                            lldb::addr_t register_data_addr) :
    Thread (process, tid),
    m_backing_thread_sp (),
    m_thread_info_valobj_sp (),
    m_name(),
    m_queue(),
    m_register_data_addr (register_data_addr)
{
    if (name)
        m_name = name;
    if (queue)
        m_queue = queue;
}


ThreadMemory::~ThreadMemory()
{
    DestroyThread();
}

void
ThreadMemory::WillResume (StateType resume_state)
{
    if (m_backing_thread_sp)
        m_backing_thread_sp->WillResume(resume_state);
}

void
ThreadMemory::ClearStackFrames ()
{
    if (m_backing_thread_sp)
        m_backing_thread_sp->ClearStackFrames();
    Thread::ClearStackFrames();
}

RegisterContextSP
ThreadMemory::GetRegisterContext ()
{
    if (!m_reg_context_sp)
        m_reg_context_sp.reset (new RegisterContextThreadMemory (*this, m_register_data_addr));
    return m_reg_context_sp;
}

RegisterContextSP
ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
{
    RegisterContextSP reg_ctx_sp;
    uint32_t concrete_frame_idx = 0;
    
    if (frame)
        concrete_frame_idx = frame->GetConcreteFrameIndex ();
    
    if (concrete_frame_idx == 0)
    {
        reg_ctx_sp = GetRegisterContext ();
    }
    else
    {
        Unwind *unwinder = GetUnwinder ();
        if (unwinder)
            reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
    }
    return reg_ctx_sp;
}

bool
ThreadMemory::CalculateStopInfo ()
{
    if (m_backing_thread_sp)
    {
        lldb::StopInfoSP backing_stop_info_sp (m_backing_thread_sp->GetPrivateStopInfo());
        if (backing_stop_info_sp)
        {
            backing_stop_info_sp->SetThread (shared_from_this());
            SetStopInfo (backing_stop_info_sp);
            return true;
        }
    }
    else
    {
        ProcessSP process_sp (GetProcess());

        if (process_sp)
        {
            OperatingSystem *os = process_sp->GetOperatingSystem ();
            if (os)
            {
                SetStopInfo (os->CreateThreadStopReason (this));
                return true;
            }
        }
    }
    return false;
}

void
ThreadMemory::RefreshStateAfterStop()
{
    if (m_backing_thread_sp)
        return m_backing_thread_sp->RefreshStateAfterStop();
    
    if (m_reg_context_sp)
        m_reg_context_sp->InvalidateAllRegisters();
}
