//===-- 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/TypeSystem.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));

    const char *uuid_cstr = NULL;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        // We are going to return a "const char *" value through the public
        // API, so we need to constify it so it gets added permanently the
        // string pool and then we don't need to worry about the lifetime of the
        // string as it will never go away once it has been put into the ConstString
        // string pool
        uuid_cstr = ConstString(module_sp->GetUUID().GetAsString()).GetCString();
    }

    if (uuid_cstr && uuid_cstr[0])
    {
        if (log)
            log->Printf ("SBModule(%p)::GetUUIDString () => %s", static_cast<void*>(module_sp.get()), uuid_cstr);
        return uuid_cstr;
    }

    if (log)
        log->Printf ("SBModule(%p)::GetUUIDString () => NULL", static_cast<void*>(module_sp.get()));
    return NULL;
}


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())
        {
            TypeSystem *type_system = module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
            if (type_system)
                sb_type = SBType (type_system->GetBuiltinTypeByName(name));
        }
    }
    return sb_type;
}

lldb::SBType
SBModule::GetBasicType(lldb::BasicType type)
{
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        TypeSystem *type_system = module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
        if (type_system)
            return SBType (type_system->GetBasicTypeFromAST(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
        {
            TypeSystem *type_system = module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
            if (type_system)
            {
                CompilerType compiler_type = type_system->GetBuiltinTypeByName(name);
                if (compiler_type)
                    retval.Append(SBType(compiler_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;
    }
}

lldb::SBFileSpec
SBModule::GetSymbolFileSpec() const
{
    lldb::SBFileSpec sb_file_spec;
    ModuleSP module_sp(GetSP());
    if (module_sp)
    {
        SymbolVendor *symbol_vendor_ptr = module_sp->GetSymbolVendor();
        if (symbol_vendor_ptr)
            sb_file_spec.SetFileSpec(symbol_vendor_ptr->GetMainFileSpec());
    }
    return sb_file_spec;
}

lldb::SBAddress
SBModule::GetObjectFileHeaderAddress() const
{
    lldb::SBAddress sb_addr;
    ModuleSP module_sp (GetSP ());
    if (module_sp)
    {
        ObjectFile *objfile_ptr = module_sp->GetObjectFile();
        if (objfile_ptr)
            sb_addr.ref() = objfile_ptr->GetHeaderAddress();
    }
    return sb_addr;
}
