//===-- SBError.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/SBError.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"

#include <stdarg.h>

using namespace lldb;
using namespace lldb_private;


SBError::SBError () :
    m_opaque_ap ()
{
}

SBError::SBError (const SBError &rhs) :
    m_opaque_ap ()
{
    if (rhs.IsValid())
        m_opaque_ap.reset (new Error(*rhs));
}


SBError::~SBError()
{
}

const SBError &
SBError::operator = (const SBError &rhs)
{
    if (rhs.IsValid())
    {
        if (m_opaque_ap.get())
            *m_opaque_ap = *rhs;
        else
            m_opaque_ap.reset (new Error(*rhs));
    }
    else
        m_opaque_ap.reset();

    return *this;
}


const char *
SBError::GetCString () const
{
    if (m_opaque_ap.get())
        return m_opaque_ap->AsCString();
    return NULL;
}

void
SBError::Clear ()
{
    if (m_opaque_ap.get())
        m_opaque_ap->Clear();
}

bool
SBError::Fail () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool ret_value = false;
    if (m_opaque_ap.get())
        ret_value = m_opaque_ap->Fail();

    if (log)
        log->Printf ("SBError(%p)::Fail () => %i",
                     static_cast<void*>(m_opaque_ap.get()), ret_value);

    return ret_value;
}

bool
SBError::Success () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    bool ret_value = true;
    if (m_opaque_ap.get())
        ret_value = m_opaque_ap->Success();

    if (log)
        log->Printf ("SBError(%p)::Success () => %i",
                     static_cast<void*>(m_opaque_ap.get()), ret_value);

    return ret_value;
}

uint32_t
SBError::GetError () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

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

    if (log)
        log->Printf ("SBError(%p)::GetError () => 0x%8.8x",
                     static_cast<void*>(m_opaque_ap.get()), err);


    return err;
}

ErrorType
SBError::GetType () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    ErrorType err_type = eErrorTypeInvalid;
    if (m_opaque_ap.get())
        err_type = m_opaque_ap->GetType();

    if (log)
        log->Printf ("SBError(%p)::GetType () => %i",
                     static_cast<void*>(m_opaque_ap.get()), err_type);

    return err_type;
}

void
SBError::SetError (uint32_t err, ErrorType type)
{
    CreateIfNeeded ();
    m_opaque_ap->SetError (err, type);
}

void
SBError::SetError (const Error &lldb_error)
{
    CreateIfNeeded ();
    *m_opaque_ap = lldb_error;
}


void
SBError::SetErrorToErrno ()
{
    CreateIfNeeded ();
    m_opaque_ap->SetErrorToErrno ();
}

void
SBError::SetErrorToGenericError ()
{
    CreateIfNeeded ();
    m_opaque_ap->SetErrorToErrno ();
}

void
SBError::SetErrorString (const char *err_str)
{
    CreateIfNeeded ();
    m_opaque_ap->SetErrorString (err_str);
}

int
SBError::SetErrorStringWithFormat (const char *format, ...)
{
    CreateIfNeeded ();
    va_list args;
    va_start (args, format);
    int num_chars = m_opaque_ap->SetErrorStringWithVarArg (format, args);
    va_end (args);
    return num_chars;
}

bool
SBError::IsValid () const
{
    return m_opaque_ap.get() != NULL;
}

void
SBError::CreateIfNeeded ()
{
    if (m_opaque_ap.get() == NULL)
        m_opaque_ap.reset(new Error ());
}


lldb_private::Error *
SBError::operator->()
{
    return m_opaque_ap.get();
}

lldb_private::Error *
SBError::get()
{
    return m_opaque_ap.get();
}

lldb_private::Error &
SBError::ref()
{
    CreateIfNeeded();
    return *m_opaque_ap;
}

const lldb_private::Error &
SBError::operator*() const
{
    // Be sure to call "IsValid()" before calling this function or it will crash
    return *m_opaque_ap;
}

bool
SBError::GetDescription (SBStream &description)
{
    if (m_opaque_ap.get())
    {
        if (m_opaque_ap->Success())
            description.Printf ("success");
        else
        {
            const char * err_string = GetCString();
            description.Printf ("error: %s",  (err_string != NULL ? err_string : ""));
        }
    }
    else
        description.Printf ("error: <NULL>");

    return true;
} 
