//===-- SBDeclaration.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/SBDeclaration.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/Declaration.h"

#include <limits.h>

using namespace lldb;
using namespace lldb_private;


SBDeclaration::SBDeclaration () :
    m_opaque_ap ()
{
}

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

SBDeclaration::SBDeclaration (const lldb_private::Declaration *lldb_object_ptr) :
    m_opaque_ap ()
{
    if (lldb_object_ptr)
        ref() = *lldb_object_ptr;
}

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

void
SBDeclaration::SetDeclaration (const lldb_private::Declaration &lldb_object_ref)
{
    ref() = lldb_object_ref;
}


SBDeclaration::~SBDeclaration ()
{
}


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


SBFileSpec
SBDeclaration::GetFileSpec () const
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    SBFileSpec sb_file_spec;
    if (m_opaque_ap.get() && m_opaque_ap->GetFile())
        sb_file_spec.SetFileSpec(m_opaque_ap->GetFile());
    
    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
SBDeclaration::GetLine () const
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    uint32_t line = 0;
    if (m_opaque_ap.get())
        line = m_opaque_ap->GetLine();
    
    if (log)
        log->Printf ("SBLineEntry(%p)::GetLine () => %u", m_opaque_ap.get(), line);
    
    return line;
}


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

void
SBDeclaration::SetFileSpec (lldb::SBFileSpec filespec)
{
    if (filespec.IsValid())
        ref().SetFile(filespec.ref());
    else
        ref().SetFile(FileSpec());
}
void
SBDeclaration::SetLine (uint32_t line)
{
    ref().SetLine(line);
}

void
SBDeclaration::SetColumn (uint32_t column)
{
    ref().SetColumn(column);
}



bool
SBDeclaration::operator == (const SBDeclaration &rhs) const
{
    lldb_private::Declaration *lhs_ptr = m_opaque_ap.get();
    lldb_private::Declaration *rhs_ptr = rhs.m_opaque_ap.get();
    
    if (lhs_ptr && rhs_ptr)
        return lldb_private::Declaration::Compare (*lhs_ptr, *rhs_ptr) == 0;
    
    return lhs_ptr == rhs_ptr;
}

bool
SBDeclaration::operator != (const SBDeclaration &rhs) const
{
    lldb_private::Declaration *lhs_ptr = m_opaque_ap.get();
    lldb_private::Declaration *rhs_ptr = rhs.m_opaque_ap.get();
    
    if (lhs_ptr && rhs_ptr)
        return lldb_private::Declaration::Compare (*lhs_ptr, *rhs_ptr) != 0;
    
    return lhs_ptr != rhs_ptr;
}

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

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

const lldb_private::Declaration &
SBDeclaration::ref() const
{
    return *m_opaque_ap;
}

bool
SBDeclaration::GetDescription (SBStream &description)
{
    Stream &strm = description.ref();
    
    if (m_opaque_ap.get())
    {
        char file_path[PATH_MAX*2];
        m_opaque_ap->GetFile().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::Declaration *
SBDeclaration::get ()
{
    return m_opaque_ap.get();
}
