//===-- SBCompileUnit.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/SBCompileUnit.h"
#include "lldb/API/SBLineEntry.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"

using namespace lldb;
using namespace lldb_private;


SBCompileUnit::SBCompileUnit () :
    m_opaque_ptr (NULL)
{
}

SBCompileUnit::SBCompileUnit (lldb_private::CompileUnit *lldb_object_ptr) :
    m_opaque_ptr (lldb_object_ptr)
{
}

SBCompileUnit::SBCompileUnit(const SBCompileUnit &rhs) :
    m_opaque_ptr (rhs.m_opaque_ptr)
{
}

const SBCompileUnit &
SBCompileUnit::operator = (const SBCompileUnit &rhs)
{
    m_opaque_ptr = rhs.m_opaque_ptr;
    return *this;
}


SBCompileUnit::~SBCompileUnit ()
{
    m_opaque_ptr = NULL;
}

SBFileSpec
SBCompileUnit::GetFileSpec () const
{
    SBFileSpec file_spec;
    if (m_opaque_ptr)
        file_spec.SetFileSpec(*m_opaque_ptr);
    return file_spec;
}

uint32_t
SBCompileUnit::GetNumLineEntries () const
{
    if (m_opaque_ptr)
    {
        LineTable *line_table = m_opaque_ptr->GetLineTable ();
        if (line_table)
            return line_table->GetSize();
    }
    return 0;
}

SBLineEntry
SBCompileUnit::GetLineEntryAtIndex (uint32_t idx) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBLineEntry sb_line_entry;
    if (m_opaque_ptr)
    {
        LineTable *line_table = m_opaque_ptr->GetLineTable ();
        if (line_table)
        {
            LineEntry line_entry;
            if (line_table->GetLineEntryAtIndex(idx, line_entry))
                sb_line_entry.SetLineEntry(line_entry);
        }
    }

    if (log)
    {
        SBStream sstr;
        sb_line_entry.GetDescription (sstr);
        log->Printf ("SBCompileUnit(%p)::GetLineEntryAtIndex (idx=%u) => SBLineEntry(%p): '%s'",
                     static_cast<void*>(m_opaque_ptr), idx,
                     static_cast<void*>(sb_line_entry.get()), sstr.GetData());
    }

    return sb_line_entry;
}

uint32_t
SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec *inline_file_spec) const
{
    const bool exact = true;
    return FindLineEntryIndex (start_idx, line, inline_file_spec, exact);
}

uint32_t
SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec *inline_file_spec, bool exact) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t index = UINT32_MAX;
    if (m_opaque_ptr)
    {
        FileSpec file_spec;
        if (inline_file_spec && inline_file_spec->IsValid())
            file_spec = inline_file_spec->ref();
        else
            file_spec = *m_opaque_ptr;

        index = m_opaque_ptr->FindLineEntry (start_idx,
                                             line,
                                             inline_file_spec ? inline_file_spec->get() : NULL,
                                             exact,
                                             NULL);
    }

    if (log)
    {
        SBStream sstr;
        if (index == UINT32_MAX)
        {
            log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => NOT FOUND",
                         static_cast<void*>(m_opaque_ptr), start_idx, line,
                         inline_file_spec
                            ? static_cast<const void*>(inline_file_spec->get())
                            : NULL);
        }
        else
        {
            log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => %u",
                         static_cast<void*>(m_opaque_ptr), start_idx, line,
                         inline_file_spec
                            ? static_cast<const void*>(inline_file_spec->get())
                            : NULL,
                         index);
        }
    }

    return index;
}

uint32_t
SBCompileUnit::GetNumSupportFiles () const
{
    if (m_opaque_ptr)
    {
        FileSpecList& support_files = m_opaque_ptr->GetSupportFiles ();
        return support_files.GetSize();
    }
    return 0;
}



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




SBFileSpec
SBCompileUnit::GetSupportFileAtIndex (uint32_t idx) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBFileSpec sb_file_spec;
    if (m_opaque_ptr)
    {
        FileSpecList &support_files = m_opaque_ptr->GetSupportFiles ();
        FileSpec file_spec = support_files.GetFileSpecAtIndex(idx);
        sb_file_spec.SetFileSpec(file_spec);
    }

    if (log)
    {
        SBStream sstr;
        sb_file_spec.GetDescription (sstr);
        log->Printf ("SBCompileUnit(%p)::GetGetFileSpecAtIndex (idx=%u) => SBFileSpec(%p): '%s'",
                     static_cast<void*>(m_opaque_ptr), idx,
                     static_cast<const void*>(sb_file_spec.get()),
                     sstr.GetData());
    }

    return sb_file_spec;
}

uint32_t
SBCompileUnit::FindSupportFileIndex (uint32_t start_idx, const SBFileSpec &sb_file, bool full)
{
    if (m_opaque_ptr)
    {
	FileSpecList &support_files = m_opaque_ptr->GetSupportFiles ();
	return support_files.FindFileIndex(start_idx, sb_file.ref(), full);
    }
    return 0;
}

lldb::LanguageType
SBCompileUnit::GetLanguage ()
{
    if (m_opaque_ptr)
        return m_opaque_ptr->GetLanguage();
    return lldb::eLanguageTypeUnknown;
}

bool
SBCompileUnit::IsValid () const
{
    return m_opaque_ptr != NULL;
}

bool
SBCompileUnit::operator == (const SBCompileUnit &rhs) const
{
    return m_opaque_ptr == rhs.m_opaque_ptr;
}

bool
SBCompileUnit::operator != (const SBCompileUnit &rhs) const
{
    return m_opaque_ptr != rhs.m_opaque_ptr;
}

const lldb_private::CompileUnit *
SBCompileUnit::operator->() const
{
    return m_opaque_ptr;
}

const lldb_private::CompileUnit &
SBCompileUnit::operator*() const
{
    return *m_opaque_ptr;
}

lldb_private::CompileUnit *
SBCompileUnit::get ()
{
    return m_opaque_ptr;
}

void
SBCompileUnit::reset (lldb_private::CompileUnit *lldb_object_ptr)
{
    m_opaque_ptr = lldb_object_ptr;
}

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

    if (m_opaque_ptr)
    {
        m_opaque_ptr->Dump (&strm, false);
    }
    else
        strm.PutCString ("No value");
    
    return true;
}
