//===-- SBFileSpec.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/SBFileSpec.h"
#include "lldb/API/SBStream.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"

using namespace lldb;
using namespace lldb_private;



SBFileSpec::SBFileSpec () :
    m_opaque_ap(new lldb_private::FileSpec())
{
}

SBFileSpec::SBFileSpec (const SBFileSpec &rhs) :
    m_opaque_ap(new lldb_private::FileSpec(*rhs.m_opaque_ap))
{
}

SBFileSpec::SBFileSpec (const lldb_private::FileSpec& fspec) :
    m_opaque_ap(new lldb_private::FileSpec(fspec))
{
}

// Deprected!!!
SBFileSpec::SBFileSpec (const char *path) :
    m_opaque_ap(new FileSpec (path, true))
{
}

SBFileSpec::SBFileSpec (const char *path, bool resolve) :
    m_opaque_ap(new FileSpec (path, resolve))
{
}

SBFileSpec::~SBFileSpec ()
{
}

const SBFileSpec &
SBFileSpec::operator = (const SBFileSpec &rhs)
{
    if (this != &rhs)
        *m_opaque_ap = *rhs.m_opaque_ap;
    return *this;
}

bool
SBFileSpec::IsValid() const
{
    return *m_opaque_ap;
}

bool
SBFileSpec::Exists () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool result = m_opaque_ap->Exists();

    if (log)
        log->Printf ("SBFileSpec(%p)::Exists () => %s", m_opaque_ap.get(), (result ? "true" : "false"));

    return result;
}

bool
SBFileSpec::ResolveExecutableLocation ()
{
    return m_opaque_ap->ResolveExecutableLocation ();
}

int
SBFileSpec::ResolvePath (const char *src_path, char *dst_path, size_t dst_len)
{
    return lldb_private::FileSpec::Resolve (src_path, dst_path, dst_len);
}

const char *
SBFileSpec::GetFilename() const
{
    const char *s = m_opaque_ap->GetFilename().AsCString();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (s)
            log->Printf ("SBFileSpec(%p)::GetFilename () => \"%s\"", m_opaque_ap.get(), s);
        else
            log->Printf ("SBFileSpec(%p)::GetFilename () => NULL", m_opaque_ap.get());
    }

    return s;
}

const char *
SBFileSpec::GetDirectory() const
{
    const char *s = m_opaque_ap->GetDirectory().AsCString();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (s)
            log->Printf ("SBFileSpec(%p)::GetDirectory () => \"%s\"", m_opaque_ap.get(), s);
        else
            log->Printf ("SBFileSpec(%p)::GetDirectory () => NULL", m_opaque_ap.get());
    }
    return s;
}

uint32_t
SBFileSpec::GetPath (char *dst_path, size_t dst_len) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t result = m_opaque_ap->GetPath (dst_path, dst_len);

    if (log)
        log->Printf ("SBFileSpec(%p)::GetPath (dst_path=\"%.*s\", dst_len=%" PRIu64 ") => %u",
                     m_opaque_ap.get(), result, dst_path, (uint64_t)dst_len, result);

    if (result == 0 && dst_path && dst_len > 0)
        *dst_path = '\0';
    return result;
}


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

const lldb_private::FileSpec *
SBFileSpec::get() const
{
    return m_opaque_ap.get();
}


const lldb_private::FileSpec &
SBFileSpec::operator*() const
{
    return *m_opaque_ap.get();
}

const lldb_private::FileSpec &
SBFileSpec::ref() const
{
    return *m_opaque_ap.get();
}


void
SBFileSpec::SetFileSpec (const lldb_private::FileSpec& fs)
{
    *m_opaque_ap = fs;
}

bool
SBFileSpec::GetDescription (SBStream &description) const
{
    Stream &strm = description.ref();
    char path[PATH_MAX];
    if (m_opaque_ap->GetPath(path, sizeof(path)))
        strm.PutCString (path);    
    return true;
}
