//===-- 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
{
    Log *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
{
    Log *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();
}
