//===-- SBLineEntry.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <limits.h>

#include "lldb/API/SBLineEntry.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Log.h"
#include "lldb/Symbol/LineEntry.h"

using namespace lldb;
using namespace lldb_private;


SBLineEntry::SBLineEntry () :
    m_opaque_ap ()
{
}

SBLineEntry::SBLineEntry (const SBLineEntry &rhs) :
    m_opaque_ap ()
{
    if (rhs.IsValid())
        ref() = rhs.ref();
}

SBLineEntry::SBLineEntry (const lldb_private::LineEntry *lldb_object_ptr) :
    m_opaque_ap ()
{
    if (lldb_object_ptr)
        ref() = *lldb_object_ptr;
}

const SBLineEntry &
SBLineEntry::operator = (const SBLineEntry &rhs)
{
    if (this != &rhs)
    {
        if (rhs.IsValid())
            ref() = rhs.ref();
        else
            m_opaque_ap.reset();
    }
    return *this;
}

void
SBLineEntry::SetLineEntry (const lldb_private::LineEntry &lldb_object_ref)
{
    ref() = lldb_object_ref;
}


SBLineEntry::~SBLineEntry ()
{
}


SBAddress
SBLineEntry::GetStartAddress () const
{

    SBAddress sb_address;
    if (m_opaque_ap.get())
        sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress());

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        StreamString sstr;
        const Address *addr = sb_address.get();
        if (addr)
            addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4);
        log->Printf ("SBLineEntry(%p)::GetStartAddress () => SBAddress (%p): %s", 
                     m_opaque_ap.get(), sb_address.get(), sstr.GetData());
    }

    return sb_address;
}

SBAddress
SBLineEntry::GetEndAddress () const
{
    SBAddress sb_address;
    if (m_opaque_ap.get())
    {
        sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress());
        sb_address.OffsetAddress(m_opaque_ap->range.GetByteSize());
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        StreamString sstr;
        const Address *addr = sb_address.get();
        if (addr)
            addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4);
        log->Printf ("SBLineEntry(%p)::GetEndAddress () => SBAddress (%p): %s", 
                     m_opaque_ap.get(), sb_address.get(), sstr.GetData());
    }
    return sb_address;
}

bool
SBLineEntry::IsValid () const
{
    return m_opaque_ap.get() && m_opaque_ap->IsValid();
}


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

    SBFileSpec sb_file_spec;
    if (m_opaque_ap.get() && m_opaque_ap->file)
        sb_file_spec.SetFileSpec(m_opaque_ap->file);

    if (log)
    {
        SBStream sstr;
        sb_file_spec.GetDescription (sstr);
        log->Printf ("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s", m_opaque_ap.get(),
                     sb_file_spec.get(), sstr.GetData());
    }

    return sb_file_spec;
}

uint32_t
SBLineEntry::GetLine () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t line = 0;
    if (m_opaque_ap.get())
        line = m_opaque_ap->line;

    if (log)
        log->Printf ("SBLineEntry(%p)::GetLine () => %u", m_opaque_ap.get(), line);

    return line;
}


uint32_t
SBLineEntry::GetColumn () const
{
    if (m_opaque_ap.get())
        return m_opaque_ap->column;
    return 0;
}

void
SBLineEntry::SetFileSpec (lldb::SBFileSpec filespec)
{
    if (filespec.IsValid())
        ref().file = filespec.ref();
    else
        ref().file.Clear();
}
void
SBLineEntry::SetLine (uint32_t line)
{
    ref().line = line;
}

void
SBLineEntry::SetColumn (uint32_t column)
{
    ref().line = column;
}



bool
SBLineEntry::operator == (const SBLineEntry &rhs) const
{
    lldb_private::LineEntry *lhs_ptr = m_opaque_ap.get();
    lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_ap.get();

    if (lhs_ptr && rhs_ptr)
        return lldb_private::LineEntry::Compare (*lhs_ptr, *rhs_ptr) == 0;

    return lhs_ptr == rhs_ptr;
}

bool
SBLineEntry::operator != (const SBLineEntry &rhs) const
{
    lldb_private::LineEntry *lhs_ptr = m_opaque_ap.get();
    lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_ap.get();

    if (lhs_ptr && rhs_ptr)
        return lldb_private::LineEntry::Compare (*lhs_ptr, *rhs_ptr) != 0;

    return lhs_ptr != rhs_ptr;
}

const lldb_private::LineEntry *
SBLineEntry::operator->() const
{
    return m_opaque_ap.get();
}

lldb_private::LineEntry &
SBLineEntry::ref()
{
    if (m_opaque_ap.get() == NULL)
        m_opaque_ap.reset (new lldb_private::LineEntry ());
    return *m_opaque_ap;
}

const lldb_private::LineEntry &
SBLineEntry::ref() const
{
    return *m_opaque_ap;
}

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

    if (m_opaque_ap.get())
    {
        char file_path[PATH_MAX*2];
        m_opaque_ap->file.GetPath (file_path, sizeof (file_path));
        strm.Printf ("%s:%u", file_path, GetLine());
        if (GetColumn() > 0)
            strm.Printf (":%u", GetColumn());
    }
    else
        strm.PutCString ("No value");

    return true;
}

lldb_private::LineEntry *
SBLineEntry::get ()
{
    return m_opaque_ap.get();
}
