//===-- SBInstructionList.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/API/SBInstructionList.h"
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/SymbolContext.h"

using namespace lldb;
using namespace lldb_private;


SBInstructionList::SBInstructionList () :
    m_opaque_sp()
{
}

SBInstructionList::SBInstructionList(const SBInstructionList &rhs) :
    m_opaque_sp (rhs.m_opaque_sp)
{
}

const SBInstructionList &
SBInstructionList::operator = (const SBInstructionList &rhs)
{
    if (this != &rhs)
        m_opaque_sp = rhs.m_opaque_sp;
    return *this;
}


SBInstructionList::~SBInstructionList ()
{
}

bool
SBInstructionList::IsValid () const
{
    return m_opaque_sp.get() != NULL;
}

size_t
SBInstructionList::GetSize ()
{
    if (m_opaque_sp)
        return m_opaque_sp->GetInstructionList().GetSize();
    return 0;
}

SBInstruction
SBInstructionList::GetInstructionAtIndex (uint32_t idx)
{
    SBInstruction inst;
    if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize())
        inst.SetOpaque (m_opaque_sp, m_opaque_sp->GetInstructionList().GetInstructionAtIndex (idx));
    return inst;
}

void
SBInstructionList::Clear ()
{
    m_opaque_sp.reset();
}

void
SBInstructionList::AppendInstruction (SBInstruction insn)
{
}

void
SBInstructionList::SetDisassembler (const lldb::DisassemblerSP &opaque_sp)
{
    m_opaque_sp = opaque_sp;
}

void
SBInstructionList::Print (FILE *out)
{
    if (out == NULL)
        return;
}


bool
SBInstructionList::GetDescription (lldb::SBStream &description)
{
    if (m_opaque_sp)
    {
        size_t num_instructions = GetSize ();
        if (num_instructions)
        {
            // Call the ref() to make sure a stream is created if one deesn't 
            // exist already inside description...
            Stream &sref = description.ref();
            const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
            FormatEntity::Entry format;
            FormatEntity::Parse("${addr}: ", format);
            SymbolContext sc;
            SymbolContext prev_sc;
            for (size_t i=0; i<num_instructions; ++i)
            {
                Instruction *inst = m_opaque_sp->GetInstructionList().GetInstructionAtIndex (i).get();
                if (inst == NULL)
                    break;

                const Address &addr = inst->GetAddress();
                prev_sc = sc;
                ModuleSP module_sp (addr.GetModule());
                if (module_sp)
                {
                    module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                }

                inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, &format, 0);
                sref.EOL();
            }
            return true;
        }
    }
    return false;
}


bool
SBInstructionList::DumpEmulationForAllInstructions (const char *triple)
{
    if (m_opaque_sp)
    {
        size_t len = GetSize();
        for (size_t i = 0; i < len; ++i)
        {
            if (!GetInstructionAtIndex((uint32_t) i).DumpEmulation (triple))
                return false;
        }
    }
    return true;
}

