//===-- 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/lldb-python.h"

#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
{
    Log *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
    Log *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)
{
    Log *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;
}
