//===-- SBListener.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/SBListener.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/TimeValue.h"


using namespace lldb;
using namespace lldb_private;


SBListener::SBListener () :
    m_opaque_sp (),
    m_opaque_ptr (NULL)
{
}

SBListener::SBListener (const char *name) :
    m_opaque_sp (new Listener (name)),
    m_opaque_ptr (NULL)
{
    m_opaque_ptr = m_opaque_sp.get();

    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBListener::SBListener (name=\"%s\") => SBListener(%p)",
                     name, m_opaque_ptr);
}


SBListener::SBListener (const SBListener &rhs) :
    m_opaque_sp (rhs.m_opaque_sp),
    m_opaque_ptr (rhs.m_opaque_ptr)
{
}

const lldb::SBListener &
SBListener::operator = (const lldb::SBListener &rhs)
{
    if (this != &rhs)
    {
        m_opaque_sp = rhs.m_opaque_sp;
        m_opaque_ptr = rhs.m_opaque_ptr;
    }
    return *this;
}

SBListener::SBListener (Listener &listener) :
    m_opaque_sp (),
    m_opaque_ptr (&listener)
{
}

SBListener::~SBListener ()
{
}

bool
SBListener::IsValid() const
{
    return m_opaque_ptr != NULL;
}

void
SBListener::AddEvent (const SBEvent &event)
{
    EventSP &event_sp = event.GetSP ();
    if (event_sp)
        m_opaque_ptr->AddEvent (event_sp);
}

void
SBListener::Clear ()
{
    if (m_opaque_ptr)
        m_opaque_ptr->Clear ();
}

    uint32_t
    SBListener::StartListeningForEventClass (SBDebugger &debugger,
                                 const char *broadcaster_class, 
                                 uint32_t event_mask)
    {
        if (m_opaque_ptr)
        {
            Debugger *lldb_debugger = debugger.get();
            if (!lldb_debugger)
                return 0;
            BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
            return m_opaque_ptr->StartListeningForEventSpec (*lldb_debugger, event_spec);
        }
        else
            return 0;
    }
                                 
    bool
    SBListener::StopListeningForEventClass (SBDebugger &debugger,
                                const char *broadcaster_class,
                                uint32_t event_mask)
    {
        if (m_opaque_ptr)
        {
            Debugger *lldb_debugger = debugger.get();
            if (!lldb_debugger)
                return false;
            BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
            return m_opaque_ptr->StopListeningForEventSpec (*lldb_debugger, event_spec);
        }
        else
            return false;
    }
    
uint32_t
SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t acquired_event_mask = 0;
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        acquired_event_mask = m_opaque_ptr->StartListeningForEvents (broadcaster.get(), event_mask);
    }
    
    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
    if (log)
    {
        StreamString sstr_requested;
        StreamString sstr_acquired;
        
        Broadcaster *lldb_broadcaster = broadcaster.get();
        if (lldb_broadcaster)
        {
            const bool got_requested_names = lldb_broadcaster->GetEventNames (sstr_requested, event_mask, false);
            const bool got_acquired_names = lldb_broadcaster->GetEventNames (sstr_acquired, acquired_event_mask, false);
            log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p): %s, event_mask=0x%8.8x%s%s%s) => 0x%8.8x%s%s%s",
                         m_opaque_ptr, 
                         lldb_broadcaster, 
                         lldb_broadcaster->GetBroadcasterName().GetCString(), 
                         event_mask, 
                         got_requested_names ? " (" : "",
                         sstr_requested.GetData(),
                         got_requested_names ? ")" : "",
                         acquired_event_mask,
                         got_acquired_names ? " (" : "",
                         sstr_acquired.GetData(),
                         got_acquired_names ? ")" : "");
        }
        else
        {
            log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x", 
                         m_opaque_ptr, 
                         lldb_broadcaster, 
                         event_mask, 
                         acquired_event_mask);
            
        }
    }

    return acquired_event_mask;
}

bool
SBListener::StopListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
{
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        return m_opaque_ptr->StopListeningForEvents (broadcaster.get(), event_mask);
    }
    return false;
}

bool
SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (timeout_secs == UINT32_MAX)
        {
            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p))...",
                         m_opaque_ptr, event.get());
        }
        else
        {
            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...",
                         m_opaque_ptr, timeout_secs, event.get());
        }
    }
    bool success = false;

    if (m_opaque_ptr)
    {
        TimeValue time_value;
        if (timeout_secs != UINT32_MAX)
        {
            assert (timeout_secs != 0); // Take this out after all calls with timeout set to zero have been removed....
            time_value = TimeValue::Now();
            time_value.OffsetWithSeconds (timeout_secs);
        }
        EventSP event_sp;
        if (m_opaque_ptr->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
        {
            event.reset (event_sp);
            success = true;
        }
    }

    if (log)
    {
        if (timeout_secs == UINT32_MAX)
        {
            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p)) => %i",
                         m_opaque_ptr, event.get(), success);
        }
        else
        {
            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i",
                         m_opaque_ptr, timeout_secs, event.get(), success);
        }
    }
    if (!success)
        event.reset (NULL);
    return success;
}

bool
SBListener::WaitForEventForBroadcaster
(
    uint32_t num_seconds,
    const SBBroadcaster &broadcaster,
    SBEvent &event
)
{
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        TimeValue time_value;
        if (num_seconds != UINT32_MAX)
        {
            time_value = TimeValue::Now();
            time_value.OffsetWithSeconds (num_seconds);
        }
        EventSP event_sp;
        if (m_opaque_ptr->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
                                                         broadcaster.get(),
                                                         event_sp))
        {
            event.reset (event_sp);
            return true;
        }

    }
    event.reset (NULL);
    return false;
}

bool
SBListener::WaitForEventForBroadcasterWithType
(
    uint32_t num_seconds,
    const SBBroadcaster &broadcaster,
    uint32_t event_type_mask,
    SBEvent &event
)
{
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        TimeValue time_value;
        if (num_seconds != UINT32_MAX)
        {
            time_value = TimeValue::Now();
            time_value.OffsetWithSeconds (num_seconds);
        }
        EventSP event_sp;
        if (m_opaque_ptr->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
                                                              broadcaster.get(),
                                                              event_type_mask,
                                                              event_sp))
        {
            event.reset (event_sp);
            return true;
        }
    }
    event.reset (NULL);
    return false;
}

bool
SBListener::PeekAtNextEvent (SBEvent &event)
{
    if (m_opaque_ptr)
    {
        event.reset (m_opaque_ptr->PeekAtNextEvent ());
        return event.IsValid();
    }
    event.reset (NULL);
    return false;
}

bool
SBListener::PeekAtNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
{
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        event.reset (m_opaque_ptr->PeekAtNextEventForBroadcaster (broadcaster.get()));
        return event.IsValid();
    }
    event.reset (NULL);
    return false;
}

bool
SBListener::PeekAtNextEventForBroadcasterWithType (const SBBroadcaster &broadcaster, uint32_t event_type_mask,
                                                   SBEvent &event)
{
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        event.reset(m_opaque_ptr->PeekAtNextEventForBroadcasterWithType (broadcaster.get(), event_type_mask));
        return event.IsValid();
    }
    event.reset (NULL);
    return false;
}

bool
SBListener::GetNextEvent (SBEvent &event)
{
    if (m_opaque_ptr)
    {
        EventSP event_sp;
        if (m_opaque_ptr->GetNextEvent (event_sp))
        {
            event.reset (event_sp);
            return true;
        }
    }
    event.reset (NULL);
    return false;
}

bool
SBListener::GetNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
{
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        EventSP event_sp;
        if (m_opaque_ptr->GetNextEventForBroadcaster (broadcaster.get(), event_sp))
        {
            event.reset (event_sp);
            return true;
        }
    }
    event.reset (NULL);
    return false;
}

bool
SBListener::GetNextEventForBroadcasterWithType
(
    const SBBroadcaster &broadcaster,
    uint32_t event_type_mask,
    SBEvent &event
)
{
    if (m_opaque_ptr && broadcaster.IsValid())
    {
        EventSP event_sp;
        if (m_opaque_ptr->GetNextEventForBroadcasterWithType (broadcaster.get(),
                                                              event_type_mask,
                                                              event_sp))
        {
            event.reset (event_sp);
            return true;
        }
    }
    event.reset (NULL);
    return false;
}

bool
SBListener::HandleBroadcastEvent (const SBEvent &event)
{
    if (m_opaque_ptr)
        return m_opaque_ptr->HandleBroadcastEvent (event.GetSP());
    return false;
}

Listener *
SBListener::operator->() const
{
    return m_opaque_ptr;
}

Listener *
SBListener::get() const
{
    return m_opaque_ptr;
}

void
SBListener::reset(Listener *listener, bool owns)
{
    if (owns)
        m_opaque_sp.reset (listener);
    else
        m_opaque_sp.reset ();
    m_opaque_ptr = listener;
}

Listener &
SBListener::ref() const
{
    return *m_opaque_ptr;    
}

Listener &
SBListener::operator *()
{
    return *m_opaque_ptr;
}

const Listener &
SBListener::operator *() const
{
    return *m_opaque_ptr;
}


