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

    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 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())
            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;
    }
}

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;
}
