//===-- 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/Section.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.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"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.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;
  Status 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, 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);
    llvm::DenseSet<SymbolFile *> searched_symbol_files;
    const uint32_t num_matches = module_sp->FindTypes(
        sc, name, exact_match, UINT32_MAX, searched_symbol_files, 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) {
  llvm::VersionTuple version;
  if (ModuleSP module_sp = GetSP())
    version = module_sp->GetVersion();
  uint32_t result = 0;
  if (!version.empty())
    ++result;
  if (version.getMinor())
    ++result;
  if(version.getSubminor())
    ++result;

  if (!versions)
    return result;

  if (num_versions > 0)
    versions[0] = version.empty() ? UINT32_MAX : version.getMajor();
  if (num_versions > 1)
    versions[1] = version.getMinor().getValueOr(UINT32_MAX);
  if (num_versions > 2)
    versions[2] = version.getSubminor().getValueOr(UINT32_MAX);
  for (uint32_t i = 3; i < num_versions; ++i)
    versions[i] = UINT32_MAX;
  return result;
}

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