//===-- 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", 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", 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", 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", 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;
} 
