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

#include "lldb/Target/ThreadPlan.h"

// C Includes
#include <string.h>
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Value.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

#pragma mark ThreadPlanTracer

ThreadPlanTracer::ThreadPlanTracer (Thread &thread, lldb::StreamSP &stream_sp) :
    m_single_step(true),
    m_enabled (false),
    m_thread (thread),
    m_stream_sp (stream_sp)
{
}

ThreadPlanTracer::ThreadPlanTracer (Thread &thread) :
    m_single_step(true),
    m_enabled (false),
    m_thread (thread),
    m_stream_sp ()
{
}

Stream *
ThreadPlanTracer::GetLogStream ()
{
    
    if (m_stream_sp.get())
        return m_stream_sp.get();
    else
        return &(m_thread.GetProcess().GetTarget().GetDebugger().GetOutputStream());
}

void 
ThreadPlanTracer::Log()
{
    SymbolContext sc;
    bool show_frame_index = false;
    bool show_fullpaths = false;
    
    m_thread.GetStackFrameAtIndex(0)->Dump (GetLogStream(), show_frame_index, show_fullpaths);
    GetLogStream()->Printf("\n");
}

bool
ThreadPlanTracer::TracerExplainsStop ()
{
    if (m_enabled && m_single_step)
    {
        lldb::StopInfoSP stop_info = m_thread.GetStopInfo();
        if (stop_info->GetStopReason() == eStopReasonTrace)
            return true;
        else 
            return false;
    }
    else
        return false;
}

#pragma mark ThreadPlanAssemblyTracer

ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread, lldb::StreamSP &stream_sp) :
    ThreadPlanTracer (thread, stream_sp),
    m_process(thread.GetProcess()),
    m_target(thread.GetProcess().GetTarget())
{
    InitializeTracer ();
}

ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread) :
    ThreadPlanTracer (thread),
    m_process(thread.GetProcess()),
    m_target(thread.GetProcess().GetTarget())
{
    InitializeTracer ();
}

void
ThreadPlanAssemblyTracer::InitializeTracer()
{
    Process &process = m_thread.GetProcess();
    Target &target = process.GetTarget();
    
    ArchSpec arch(target.GetArchitecture());
    
    m_disassembler = Disassembler::FindPlugin(arch);
    
    m_abi = process.GetABI();
    
    ModuleSP exe_module_sp (target.GetExecutableModule());
    
    if (exe_module_sp)
    {
        m_intptr_type = TypeFromUser(exe_module_sp->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, arch.GetAddressByteSize() * 8),
                                     exe_module_sp->GetClangASTContext().getASTContext());
    }
    
    const unsigned int buf_size = 32;
    
    m_buffer_sp.reset(new DataBufferHeap(buf_size, 0));
}

ThreadPlanAssemblyTracer::~ThreadPlanAssemblyTracer()
{
}

void 
ThreadPlanAssemblyTracer::TracingStarted ()
{
    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
    
    if (m_register_values.size() == 0)
    {
        for (uint32_t reg_index = 0, num_registers = reg_ctx->GetRegisterCount();
             reg_index < num_registers;
             ++reg_index)
            m_register_values.push_back(0);
    }
}

void
ThreadPlanAssemblyTracer::TracingEnded ()
{
    for (uint32_t reg_index = 0, num_registers = m_register_values.size();
         reg_index < num_registers;
         ++reg_index)
        m_register_values[reg_index] = 0;
}

static void
PadOutTo (StreamString &stream, int target)
{
    stream.Flush();

    int length = stream.GetString().length();

    if (length + 1 < target)
        stream.Printf("%*s", target - (length + 1) + 1, "");
}

void 
ThreadPlanAssemblyTracer::Log ()
{
    Stream *stream = GetLogStream ();
    
    if (!stream)
        return;
            
    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
    
    lldb::addr_t pc = reg_ctx->GetPC();
    Address pc_addr;
    bool addr_valid = false;
    
    StreamString desc;
    
    int desired_width = 0;
    
    addr_valid = m_process.GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
    
    pc_addr.Dump(&desc, &m_thread, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress);
    
    desired_width += 64;
    PadOutTo(desc, desired_width);
    
    if (m_disassembler)
    {        
        ::memset(m_buffer_sp->GetBytes(), 0, m_buffer_sp->GetByteSize());
        
        Error err;
        m_process.ReadMemory(pc, m_buffer_sp->GetBytes(), m_buffer_sp->GetByteSize(), err);
        
        if (err.Success())
        {
            DataExtractor extractor(m_buffer_sp,
                                    m_process.GetByteOrder(),
                                    m_process.GetAddressByteSize());
            
            if (addr_valid)
                m_disassembler->DecodeInstructions (pc_addr, extractor, 0, 1);
            else
                m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1);
            
            InstructionList &instruction_list = m_disassembler->GetInstructionList();
            
            if (instruction_list.GetSize())
            {
                Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
                instruction->Dump (&desc,
                                   false,
                                   NULL, 
                                   0, 
                                   NULL, 
                                   true);
            }
        }
        
        desired_width += 32;
        PadOutTo(desc, desired_width);
    }
    
    if (m_abi && m_intptr_type.GetOpaqueQualType())
    {
        ValueList value_list;
        const int num_args = 1;
        
        for (int arg_index = 0; arg_index < num_args; ++arg_index)
        {
            Value value;
            value.SetValueType (Value::eValueTypeScalar);
            value.SetContext (Value::eContextTypeClangType, m_intptr_type.GetOpaqueQualType());
            value_list.PushValue (value);
        }
        
        if (m_abi->GetArgumentValues (m_thread, value_list))
        {                
            for (int arg_index = 0; arg_index < num_args; ++arg_index)
            {
                desc.Printf("arg[%d]=%llx", arg_index, value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
                
                if (arg_index + 1 < num_args)
                    desc.Printf(", ");
            }
        }
    }
    
    desired_width += 20;
    PadOutTo(desc, desired_width);
    
    for (uint32_t reg_index = 0, num_registers = reg_ctx->GetRegisterCount();
         reg_index < num_registers;
         ++reg_index)
    {
        uint64_t reg_value = reg_ctx->ReadRegisterAsUnsigned(reg_index, 0x0);
        
        if (reg_value != m_register_values[reg_index])
        {
            desc.Printf ("%s:0x%llx->0x%llx ", reg_ctx->GetRegisterName(reg_index), m_register_values[reg_index], reg_value);
            
            m_register_values[reg_index] = reg_value;
        }
    }
    
    stream->Printf ("Single-step: %s\n", desc.GetString().c_str());
}
