//===-- SBEvent.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/SBEvent.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBStream.h"

#include "lldb/Core/Event.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Target/Process.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Interpreter/CommandInterpreter.h"

using namespace lldb;
using namespace lldb_private;


SBEvent::SBEvent () :
    m_event_sp (),
    m_opaque_ptr (NULL)
{
}

SBEvent::SBEvent (uint32_t event_type, const char *cstr, uint32_t cstr_len) :
    m_event_sp (new Event (event_type, new EventDataBytes (cstr, cstr_len))),
    m_opaque_ptr (m_event_sp.get())
{
}

SBEvent::SBEvent (EventSP &event_sp) :
    m_event_sp (event_sp),
    m_opaque_ptr (event_sp.get())
{
}

SBEvent::SBEvent (const SBEvent &rhs) :
    m_event_sp (rhs.m_event_sp),
    m_opaque_ptr (rhs.m_opaque_ptr)
{
    
}
    
const SBEvent &
SBEvent::operator = (const SBEvent &rhs)
{
    if (this != &rhs)
    {
        m_event_sp = rhs.m_event_sp;
        m_opaque_ptr = rhs.m_opaque_ptr;
    }
    return *this;
}

SBEvent::~SBEvent()
{
}

const char *
SBEvent::GetDataFlavor ()
{
    Event *lldb_event = get();
    if (lldb_event)
    {
        EventData *event_data = lldb_event->GetData();
        if (event_data)
            return lldb_event->GetData()->GetFlavor().AsCString();
    }
    return NULL;
}

uint32_t
SBEvent::GetType () const
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    const Event *lldb_event = get();
    uint32_t event_type = 0;
    if (lldb_event)
        event_type = lldb_event->GetType();

    if (log)
    {
        StreamString sstr;
        if (lldb_event && lldb_event->GetBroadcaster() && lldb_event->GetBroadcaster()->GetEventNames(sstr, event_type, true))
            log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x (%s)", get(), event_type, sstr.GetData());
        else
            log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x", get(), event_type);

    }

    return event_type;
}

SBBroadcaster
SBEvent::GetBroadcaster () const
{
    SBBroadcaster broadcaster;
    const Event *lldb_event = get();
    if (lldb_event)
        broadcaster.reset (lldb_event->GetBroadcaster(), false);
    return broadcaster;
}

const char *
SBEvent::GetBroadcasterClass () const
{
    const Event *lldb_event = get();
    if (lldb_event)
        return lldb_event->GetBroadcaster()->GetBroadcasterClass().AsCString();
    else
        return "unknown class";
}

bool
SBEvent::BroadcasterMatchesPtr (const SBBroadcaster *broadcaster)
{
    if (broadcaster)
        return BroadcasterMatchesRef (*broadcaster);
    return false;
}

bool
SBEvent::BroadcasterMatchesRef (const SBBroadcaster &broadcaster)
{

    Event *lldb_event = get();
    bool success = false;
    if (lldb_event)
        success = lldb_event->BroadcasterIs (broadcaster.get());

    // For logging, this gets a little chatty so only enable this when verbose logging is on
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE));
    if (log)
        log->Printf ("SBEvent(%p)::BroadcasterMatchesRef (SBBroadcaster(%p): %s) => %i", 
                     get(),
                     broadcaster.get(),
                     broadcaster.GetName(),
                     success);

    return success;
}

void
SBEvent::Clear()
{
    Event *lldb_event = get();
    if (lldb_event)
        lldb_event->Clear();
}

EventSP &
SBEvent::GetSP () const
{
    return m_event_sp;
}

Event *
SBEvent::get() const
{
    // There is a dangerous accessor call GetSharedPtr which can be used, so if
    // we have anything valid in m_event_sp, we must use that since if it gets
    // used by a function that puts something in there, then it won't update
    // m_opaque_ptr...
    if (m_event_sp)
        m_opaque_ptr = m_event_sp.get();

    return m_opaque_ptr;
}

void
SBEvent::reset (EventSP &event_sp)
{
    m_event_sp = event_sp;
    m_opaque_ptr = m_event_sp.get();
}

void
SBEvent::reset (Event* event_ptr)
{
    m_opaque_ptr = event_ptr;
    m_event_sp.reset();
}

bool
SBEvent::IsValid() const
{
    // Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get()
    // accessor. See comments in SBEvent::get()....
    return SBEvent::get() != NULL;

}

const char *
SBEvent::GetCStringFromEvent (const SBEvent &event)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBEvent(%p)::GetCStringFromEvent () => \"%s\"", 
                     event.get(), 
                     reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event.get())));

    return reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event.get()));
}


bool
SBEvent::GetDescription (SBStream &description)
{
    Stream &strm = description.ref();

    if (get())
    {
        m_opaque_ptr->Dump (&strm);
    }
    else
        strm.PutCString ("No value");

    return true;
}

bool
SBEvent::GetDescription (SBStream &description) const
{
    Stream &strm = description.ref();

    if (get())
    {
        m_opaque_ptr->Dump (&strm);
    }
    else
        strm.PutCString ("No value");

    return true;
}
