//===-- 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/lldb-python.h"

#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/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.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/SectionLoadList.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_thread (thread),
    m_single_step(true),
    m_enabled (false),
    m_stream_sp (stream_sp)
{
}

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

Stream *
ThreadPlanTracer::GetLogStream ()
{
    
    if (m_stream_sp.get())
        return m_stream_sp.get();
    else
    {
        TargetSP target_sp (m_thread.CalculateTarget());
        if (target_sp)
            return target_sp->GetDebugger().GetOutputFile().get();
    }
    return NULL;
}

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

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_disassembler_sp (),
    m_intptr_type (),
    m_register_values ()
{
}

ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread) :
    ThreadPlanTracer (thread),
    m_disassembler_sp (),
    m_intptr_type (),
    m_register_values ()
{
}

Disassembler *
ThreadPlanAssemblyTracer::GetDisassembler ()
{
    if (m_disassembler_sp.get() == NULL)
        m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL, NULL);
    return m_disassembler_sp.get();
}

TypeFromUser
ThreadPlanAssemblyTracer::GetIntPointerType()
{
    if (!m_intptr_type.IsValid ())
    {
        TargetSP target_sp (m_thread.CalculateTarget());
        if (target_sp)
        {
            Module *exe_module = target_sp->GetExecutableModulePointer();
        
            if (exe_module)
            {
                m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8));
            }
        }        
    }
    return m_intptr_type;
}



ThreadPlanAssemblyTracer::~ThreadPlanAssemblyTracer()
{
}

void 
ThreadPlanAssemblyTracer::TracingStarted ()
{
    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
    
    if (m_register_values.size() == 0)
        m_register_values.resize (reg_ctx->GetRegisterCount());
}

void
ThreadPlanAssemblyTracer::TracingEnded ()
{
    m_register_values.clear();
}

void 
ThreadPlanAssemblyTracer::Log ()
{
    Stream *stream = GetLogStream ();
    
    if (!stream)
        return;
            
    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
    
    lldb::addr_t pc = reg_ctx->GetPC();
    ProcessSP process_sp (m_thread.GetProcess());
    Address pc_addr;
    bool addr_valid = false;
    uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
    addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
    
    pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress);
    stream->PutCString (" ");
    
    Disassembler *disassembler = GetDisassembler();
    if (disassembler)
    {        
        Error err;
        process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);
        
        if (err.Success())
        {
            DataExtractor extractor(buffer, sizeof(buffer), 
                                    process_sp->GetByteOrder(), 
                                    process_sp->GetAddressByteSize());
            
			bool data_from_file = false;
            if (addr_valid)
                disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false, data_from_file);
            else
                disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false, data_from_file);
            
            InstructionList &instruction_list = disassembler->GetInstructionList();
            const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();

            if (instruction_list.GetSize())
            {
                const bool show_bytes = true;
                const bool show_address = true;
                Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
                const char *disassemble_format = "${addr-file-or-load}: ";
                instruction->Dump (stream,
                                   max_opcode_byte_size,
                                   show_address,
                                   show_bytes,
                                   NULL,
                                   NULL,
                                   NULL,
                                   disassemble_format);
            }
        }
    }
    
    const ABI *abi = process_sp->GetABI().get();
    TypeFromUser intptr_type = GetIntPointerType();
    
    if (abi && intptr_type.IsValid())
    {
        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, intptr_type.GetOpaqueQualType());
            value.SetClangType (intptr_type);
            value_list.PushValue (value);
        }
        
        if (abi->GetArgumentValues (m_thread, value_list))
        {                
            for (int arg_index = 0; arg_index < num_args; ++arg_index)
            {
                stream->Printf("\n\targ[%d]=%llx", arg_index, value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
                
                if (arg_index + 1 < num_args)
                    stream->PutCString (", ");
            }
        }
    }
    
    
    RegisterValue reg_value;
    for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
         reg_num < num_registers;
         ++reg_num)
    {
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
        if (reg_ctx->ReadRegister (reg_info, reg_value))
        {
            assert (reg_num < m_register_values.size());
            if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid || 
                reg_value != m_register_values[reg_num])
            {
                if (reg_value.GetType() != RegisterValue::eTypeInvalid)
                {
                    stream->PutCString ("\n\t");
                    reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
                }
            }
            m_register_values[reg_num] = reg_value;
        }
    }
    stream->EOL();
    stream->Flush();
}
