//===-- 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 executableModuleSP (target.GetExecutableModule());
    TypeList *type_list = executableModuleSP->GetTypeList();
    
    if (type_list)
    {
        m_intptr_type = TypeFromUser(type_list->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, arch.GetAddressByteSize() * 8),
                                     type_list->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();
    
    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 const char *Padding(int length)
{
    const int padding_size = 256;

    static char* padding = NULL;
    static int prev_length = 256;

    if (!padding) {
        padding = new char[padding_size];
        memset(padding, ' ', padding_size);
    }

    if (length > 255)
        length = 255;

    if (prev_length < 256)
        padding[prev_length] = ' ';

    padding[length] = '\0';

    prev_length = length;

    return padding;
}

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

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

    if (length + 1 < target)
        stream.PutCString(Padding(target - (length + 1)));

    stream.PutCString(" ");
}

void ThreadPlanAssemblyTracer::Log ()
{
    Stream *stream = GetLogStream ();
    
    if (!stream)
        return;
            
    RegisterContext *reg_ctx = m_thread.GetRegisterContext();
    
    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)
    {        
        bzero(m_buffer_sp->GetBytes(), 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());
}
