//===-- SBModule.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/SBModule.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBModuleSpec.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;


SBModule::SBModule () :
    m_opaque_sp ()
{
}

SBModule::SBModule (const lldb::ModuleSP& module_sp) :
    m_opaque_sp (module_sp)
{
}

SBModule::SBModule(const SBModuleSpec &module_spec) :
    m_opaque_sp ()
{
    ModuleSP module_sp;
    Error error = ModuleList::GetSharedModule (*module_spec.m_opaque_ap,
                                               module_sp,
                                               NULL,
                                               NULL,
                                               NULL);
    if (module_sp)
        SetSP(module_sp);
}

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

SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) :
    m_opaque_sp ()
{
    ProcessSP process_sp (process.GetSP());
    if (process_sp)
    {
        m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(), header_addr);
        if (m_opaque_sp)
        {
            Target &target = process_sp->GetTarget();
            bool changed = false;
            m_opaque_sp->SetLoadAddress(target, 0, true, changed);
            target.GetImages().Append(m_opaque_sp);
        }
    }
}

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

SBModule::~SBModule ()
{
}

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

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

SBFileSpec
SBModule::GetFileSpec () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBFileSpec file_spec;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        file_spec.SetFileSpec(module_sp->GetFileSpec());

    if (log)
        log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)",
                     static_cast<void*>(module_sp.get()),
                     static_cast<const void*>(file_spec.get()));

    return file_spec;
}

lldb::SBFileSpec
SBModule::GetPlatformFileSpec () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBFileSpec file_spec;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        file_spec.SetFileSpec(module_sp->GetPlatformFileSpec());

    if (log)
        log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
                     static_cast<void*>(module_sp.get()),
                     static_cast<const void*>(file_spec.get()));

    return file_spec;
}

bool
SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
{
    bool result = false;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        module_sp->SetPlatformFileSpec(*platform_file);
        result = true;
    }

    if (log)
        log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s)) => %i",
                     static_cast<void*>(module_sp.get()),
                     static_cast<const void*>(platform_file.get()),
                     platform_file->GetPath().c_str(), result);
    return result;
}

lldb::SBFileSpec
SBModule::GetRemoteInstallFileSpec ()
{
    SBFileSpec sb_file_spec;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        sb_file_spec.SetFileSpec (module_sp->GetRemoteInstallFileSpec());
    return sb_file_spec;
}

bool
SBModule::SetRemoteInstallFileSpec (lldb::SBFileSpec &file)
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        module_sp->SetRemoteInstallFileSpec(file.ref());
        return true;
    }
    return false;
}


const uint8_t *
SBModule::GetUUIDBytes () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    const uint8_t *uuid_bytes = NULL;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes();

    if (log)
    {
        if (uuid_bytes)
        {
            StreamString s;
            module_sp->GetUUID().Dump (&s);
            log->Printf ("SBModule(%p)::GetUUIDBytes () => %s",
                         static_cast<void*>(module_sp.get()), s.GetData());
        }
        else
            log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL",
                         static_cast<void*>(module_sp.get()));
    }
    return uuid_bytes;
}


const char *
SBModule::GetUUIDString () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    static char uuid_string_buffer[80];
    const char *uuid_c_string = NULL;
    std::string uuid_string;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        uuid_string = module_sp->GetUUID().GetAsString();

    if (!uuid_string.empty())
    {
        strncpy (uuid_string_buffer, uuid_string.c_str(), sizeof (uuid_string_buffer));
        uuid_string_buffer[sizeof (uuid_string_buffer) - 1] = '\0';
        uuid_c_string = uuid_string_buffer;
    }

    if (log)
    {
        if (!uuid_string.empty())
        {
            StreamString s;
            module_sp->GetUUID().Dump (&s);
            log->Printf ("SBModule(%p)::GetUUIDString () => %s",
                         static_cast<void*>(module_sp.get()), s.GetData());
        }
        else
            log->Printf ("SBModule(%p)::GetUUIDString () => NULL",
                         static_cast<void*>(module_sp.get()));
    }
    return uuid_c_string;
}


bool
SBModule::operator == (const SBModule &rhs) const
{
    if (m_opaque_sp)
        return m_opaque_sp.get() == rhs.m_opaque_sp.get();
    return false;
}

bool
SBModule::operator != (const SBModule &rhs) const
{
    if (m_opaque_sp)
        return m_opaque_sp.get() != rhs.m_opaque_sp.get();
    return false;
}

ModuleSP
SBModule::GetSP () const
{
    return m_opaque_sp;
}

void
SBModule::SetSP (const ModuleSP &module_sp)
{
    m_opaque_sp = module_sp;
}

SBAddress
SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
{
    lldb::SBAddress sb_addr;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        Address addr;
        if (module_sp->ResolveFileAddress (vm_addr, addr))
            sb_addr.ref() = addr;
    }
    return sb_addr;
}

SBSymbolContext
SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
{
    SBSymbolContext sb_sc;
    ModuleSP module_sp (GetSP ());
    if (module_sp && addr.IsValid())
        module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc);
    return sb_sc;
}

bool
SBModule::GetDescription (SBStream &description)
{
    Stream &strm = description.ref();

    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        module_sp->GetDescription (&strm);
    }
    else
        strm.PutCString ("No value");

    return true;
}

uint32_t
SBModule::GetNumCompileUnits()
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        return module_sp->GetNumCompileUnits ();
    }
    return 0;
}

SBCompileUnit
SBModule::GetCompileUnitAtIndex (uint32_t index)
{
    SBCompileUnit sb_cu;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex (index);
        sb_cu.reset(cu_sp.get());
    }
    return sb_cu;
}

static Symtab *
GetUnifiedSymbolTable (const lldb::ModuleSP& module_sp)
{
    if (module_sp)
    {
        SymbolVendor *symbols = module_sp->GetSymbolVendor();
        if (symbols)
            return symbols->GetSymtab();
    }
    return NULL;
}

size_t
SBModule::GetNumSymbols ()
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
        if (symtab)
            return symtab->GetNumSymbols();
    }
    return 0;
}

SBSymbol
SBModule::GetSymbolAtIndex (size_t idx)
{
    SBSymbol sb_symbol;
    ModuleSP module_sp (GetSP ());
    Symtab *symtab = GetUnifiedSymbolTable (module_sp);
    if (symtab)
        sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx));
    return sb_symbol;
}

lldb::SBSymbol
SBModule::FindSymbol (const char *name,
                      lldb::SymbolType symbol_type)
{
    SBSymbol sb_symbol;
    if (name && name[0])
    {
        ModuleSP module_sp (GetSP ());
        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
        if (symtab)
            sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(ConstString(name), symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny));
    }
    return sb_symbol;
}


lldb::SBSymbolContextList
SBModule::FindSymbols (const char *name, lldb::SymbolType symbol_type)
{
    SBSymbolContextList sb_sc_list;
    if (name && name[0])
    {
        ModuleSP module_sp (GetSP ());
        Symtab *symtab = GetUnifiedSymbolTable (module_sp);
        if (symtab)
        {
            std::vector<uint32_t> matching_symbol_indexes;
            const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, matching_symbol_indexes);
            if (num_matches)
            {
                SymbolContext sc;
                sc.module_sp = module_sp;
                SymbolContextList &sc_list = *sb_sc_list;
                for (size_t i=0; i<num_matches; ++i)
                {
                    sc.symbol = symtab->SymbolAtIndex (matching_symbol_indexes[i]);
                    if (sc.symbol)
                        sc_list.Append(sc);
                }
            }
        }
    }
    return sb_sc_list;
    
}



size_t
SBModule::GetNumSections ()
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        // Give the symbol vendor a chance to add to the unified section list.
        module_sp->GetSymbolVendor();
        SectionList *section_list = module_sp->GetSectionList();
        if (section_list)
            return section_list->GetSize();
    }
    return 0;
}

SBSection
SBModule::GetSectionAtIndex (size_t idx)
{
    SBSection sb_section;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        // Give the symbol vendor a chance to add to the unified section list.
        module_sp->GetSymbolVendor();
        SectionList *section_list = module_sp->GetSectionList ();

        if (section_list)
            sb_section.SetSP(section_list->GetSectionAtIndex (idx));
    }
    return sb_section;
}

lldb::SBSymbolContextList
SBModule::FindFunctions (const char *name, 
                         uint32_t name_type_mask)
{
    lldb::SBSymbolContextList sb_sc_list;
    ModuleSP module_sp (GetSP ());
    if (name && module_sp)
    {
        const bool append = true;
        const bool symbols_ok = true;
        const bool inlines_ok = true;
        module_sp->FindFunctions (ConstString(name),
                                  NULL,
                                  name_type_mask, 
                                  symbols_ok,
                                  inlines_ok,
                                  append, 
                                  *sb_sc_list);
    }
    return sb_sc_list;
}


SBValueList
SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches)
{
    SBValueList sb_value_list;
    ModuleSP module_sp (GetSP ());
    if (name && module_sp)
    {
        VariableList variable_list;
        const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name),
                                                                     NULL,
                                                                     false, 
                                                                     max_matches,
                                                                     variable_list);

        if (match_count > 0)
        {
            for (uint32_t i=0; i<match_count; ++i)
            {
                lldb::ValueObjectSP valobj_sp;
                TargetSP target_sp (target.GetSP());
                valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
                if (valobj_sp)
                    sb_value_list.Append(SBValue(valobj_sp));
            }
        }
    }
    
    return sb_value_list;
}

lldb::SBValue
SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name)
{
    SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
    if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
        return sb_value_list.GetValueAtIndex(0);
    return SBValue();
}

lldb::SBType
SBModule::FindFirstType (const char *name_cstr)
{
    SBType sb_type;
    ModuleSP module_sp (GetSP ());
    if (name_cstr && module_sp)
    {
        SymbolContext sc;
        const bool exact_match = false;
        ConstString name(name_cstr);

        sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
        
        if (!sb_type.IsValid())
            sb_type = SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
    }
    return sb_type;
}

lldb::SBType
SBModule::GetBasicType(lldb::BasicType type)
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        return SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
    return SBType();
}

lldb::SBTypeList
SBModule::FindTypes (const char *type)
{
    SBTypeList retval;
    
    ModuleSP module_sp (GetSP ());
    if (type && module_sp)
    {
        SymbolContext sc;
        TypeList type_list;
        const bool exact_match = false;
        ConstString name(type);
        const uint32_t num_matches = module_sp->FindTypes (sc,
                                                           name,
                                                           exact_match,
                                                           UINT32_MAX,
                                                           type_list);
        
        if (num_matches > 0)
        {
            for (size_t idx = 0; idx < num_matches; idx++)
            {
                TypeSP type_sp (type_list.GetTypeAtIndex(idx));
                if (type_sp)
                    retval.Append(SBType(type_sp));
            }
        }
        else
        {
            SBType sb_type(ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
            if (sb_type.IsValid())
                retval.Append(sb_type);
        }
    }

    return retval;
}

lldb::SBType
SBModule::GetTypeByID (lldb::user_id_t uid)
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        SymbolVendor* vendor = module_sp->GetSymbolVendor();
        if (vendor)
        {
            Type *type_ptr = vendor->ResolveTypeUID(uid);
            if (type_ptr)
                return SBType(type_ptr->shared_from_this());
        }
    }
    return SBType();
}

lldb::SBTypeList
SBModule::GetTypes (uint32_t type_mask)
{
    SBTypeList sb_type_list;
    
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        SymbolVendor* vendor = module_sp->GetSymbolVendor();
        if (vendor)
        {
            TypeList type_list;
            vendor->GetTypes (NULL, type_mask, type_list);
            sb_type_list.m_opaque_ap->Append(type_list);
        }
    }
    return sb_type_list;
}

SBSection
SBModule::FindSection (const char *sect_name)
{
    SBSection sb_section;
    
    ModuleSP module_sp (GetSP ());
    if (sect_name && module_sp)
    {
        // Give the symbol vendor a chance to add to the unified section list.
        module_sp->GetSymbolVendor();
        SectionList *section_list = module_sp->GetSectionList();
        if (section_list)
        {
            ConstString const_sect_name(sect_name);
            SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
            if (section_sp)
            {
                sb_section.SetSP (section_sp);
            }
        }
    }
    return sb_section;
}

lldb::ByteOrder
SBModule::GetByteOrder ()
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        return module_sp->GetArchitecture().GetByteOrder();
    return eByteOrderInvalid;
}

const char *
SBModule::GetTriple ()
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        std::string triple (module_sp->GetArchitecture().GetTriple().str());
        // Unique the string so we don't run into ownership issues since
        // the const strings put the string into the string pool once and
        // the strings never comes out
        ConstString const_triple (triple.c_str());
        return const_triple.GetCString();
    }
    return NULL;
}

uint32_t
SBModule::GetAddressByteSize()
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        return module_sp->GetArchitecture().GetAddressByteSize();
    return sizeof(void*);
}


uint32_t
SBModule::GetVersion (uint32_t *versions, uint32_t num_versions)
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
        return module_sp->GetVersion(versions, num_versions);
    else
    {
        if (versions && num_versions)
        {
            for (uint32_t i=0; i<num_versions; ++i)
                versions[i] = UINT32_MAX;
        }
        return 0;
    }
}

