//===-- SBQueue.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 <inttypes.h>

#include "lldb/API/SBQueue.h"

#include "lldb/API/SBProcess.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBQueueItem.h"

#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Queue.h"
#include "lldb/Target/QueueItem.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

namespace lldb_private
{

    class QueueImpl
    {
    public:
        QueueImpl () :
            m_queue_wp(),
            m_threads(),
            m_thread_list_fetched(false),
            m_pending_items(),
            m_pending_items_fetched(false)
        {
        }

        QueueImpl (const lldb::QueueSP &queue_sp) :
            m_queue_wp(),
            m_threads(),
            m_thread_list_fetched(false),
            m_pending_items(),
            m_pending_items_fetched(false)
        {
            m_queue_wp = queue_sp;
        }

        QueueImpl (const QueueImpl &rhs)
        {
            if (&rhs == this)
                return;
            m_queue_wp = rhs.m_queue_wp;
            m_threads = rhs.m_threads;
            m_thread_list_fetched = rhs.m_thread_list_fetched;
            m_pending_items = rhs.m_pending_items;
            m_pending_items_fetched = rhs.m_pending_items_fetched;
        }

        ~QueueImpl ()
        {
        }

        bool
        IsValid ()
        {
            return m_queue_wp.lock() != NULL;
        }

        void
        Clear ()
        {
            m_queue_wp.reset();
            m_thread_list_fetched = false;
            m_threads.clear();
            m_pending_items_fetched = false;
            m_pending_items.clear();
        }

        void
        SetQueue (const lldb::QueueSP &queue_sp)
        {
            Clear();
            m_queue_wp = queue_sp;
        }

        lldb::queue_id_t
        GetQueueID () const
        {
            lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
            lldb::QueueSP queue_sp = m_queue_wp.lock();
            if (queue_sp)
            {
                result = queue_sp->GetID();
            }
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64,
                             static_cast<const void*>(this), result);
            return result;
        }

        uint32_t
        GetIndexID () const
        {
            uint32_t result = LLDB_INVALID_INDEX32;
            lldb::QueueSP queue_sp = m_queue_wp.lock();
            if (queue_sp)
            {
                result = queue_sp->GetIndexID();
            }
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBQueueImpl(%p)::GetIndexID () => %d",
                             static_cast<const void*>(this), result);
            return result;
        }

        const char *
        GetName () const
        {
            const char *name = NULL;
            lldb::QueueSP queue_sp = m_queue_wp.lock ();
            if (queue_sp.get())
            {
                name = queue_sp->GetName();
            }

            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBQueueImpl(%p)::GetName () => %s",
                             static_cast<const void*>(this),
                             name ? name : "NULL");

            return name;
        }

        void
        FetchThreads ()
        {
            if (m_thread_list_fetched == false)
            {
                lldb::QueueSP queue_sp = m_queue_wp.lock();
                if (queue_sp)
                {
                    Process::StopLocker stop_locker;
                    if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
                    {
                        const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
                        m_thread_list_fetched = true;
                        const uint32_t num_threads = thread_list.size();
                        for (uint32_t idx = 0; idx < num_threads; ++idx)
                        {
                            ThreadSP thread_sp = thread_list[idx];
                            if (thread_sp && thread_sp->IsValid())
                            {
                                m_threads.push_back (thread_sp);
                            }
                        }
                    }
                }
            }
        }

        void
        FetchItems ()
        {
            if (m_pending_items_fetched == false)
            {
                QueueSP queue_sp = m_queue_wp.lock();
                if (queue_sp)
                {
                    Process::StopLocker stop_locker;
                    if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
                    {
                        const std::vector<QueueItemSP> queue_items(queue_sp->GetPendingItems());
                        m_pending_items_fetched = true;
                        const uint32_t num_pending_items = queue_items.size();
                        for (uint32_t idx = 0; idx < num_pending_items; ++idx)
                        {
                            QueueItemSP item = queue_items[idx];
                            if (item && item->IsValid())
                            {
                                m_pending_items.push_back (item);
                            }
                        }
                    }
                }
            }
        }

        uint32_t
        GetNumThreads ()
        {
            uint32_t result = 0;

            FetchThreads();
            if (m_thread_list_fetched)
            {
                result = m_threads.size();
            }
            return result;
        }

        lldb::SBThread
        GetThreadAtIndex (uint32_t idx)
        {
            FetchThreads();

            SBThread sb_thread;
            QueueSP queue_sp = m_queue_wp.lock();
            if (queue_sp && idx < m_threads.size())
            {
                ProcessSP process_sp = queue_sp->GetProcess();
                if (process_sp)
                {
                    ThreadSP thread_sp = m_threads[idx].lock();
                    if (thread_sp)
                    {
                        sb_thread.SetThread (thread_sp);
                    }
                }
            }
            return sb_thread;
        }

        uint32_t
        GetNumPendingItems ()
        {
            uint32_t result = 0;

            QueueSP queue_sp = m_queue_wp.lock();
            if (m_pending_items_fetched == false && queue_sp)
            {
                result = queue_sp->GetNumPendingWorkItems();
            }
            else
            {
                result = m_pending_items.size();
            }
            return result;
        }

        lldb::SBQueueItem
        GetPendingItemAtIndex (uint32_t idx)
        {
            SBQueueItem result;
            FetchItems();
            if (m_pending_items_fetched && idx < m_pending_items.size())
            {
                result.SetQueueItem (m_pending_items[idx]);
            }
            return result;
        }

        uint32_t
        GetNumRunningItems ()
        {
            uint32_t result = 0;
            QueueSP queue_sp = m_queue_wp.lock();
            if (queue_sp)
                result = queue_sp->GetNumRunningWorkItems();
            return result;
        }

        lldb::SBProcess
        GetProcess ()
        {
            SBProcess result;
            QueueSP queue_sp = m_queue_wp.lock();
            if (queue_sp)
            {
                result.SetSP (queue_sp->GetProcess());
            }
            return result;
        }

        lldb::QueueKind
        GetKind ()
        {
            lldb::QueueKind kind = eQueueKindUnknown;
            QueueSP queue_sp = m_queue_wp.lock();
            if (queue_sp)
                kind = queue_sp->GetKind();

            return kind;
        }

    private:
        lldb::QueueWP                   m_queue_wp;
        std::vector<lldb::ThreadWP>     m_threads;              // threads currently executing this queue's items
        bool                            m_thread_list_fetched;  // have we tried to fetch the threads list already?
        std::vector<lldb::QueueItemSP>  m_pending_items;       // items currently enqueued
        bool                            m_pending_items_fetched;  // have we tried to fetch the item list already?
    };

}

SBQueue::SBQueue () :
    m_opaque_sp (new QueueImpl())
{
}

SBQueue::SBQueue (const QueueSP& queue_sp) :
    m_opaque_sp (new QueueImpl (queue_sp))
{
}

SBQueue::SBQueue (const SBQueue &rhs)
{
    if (&rhs == this)
        return;

    m_opaque_sp = rhs.m_opaque_sp;
}

const lldb::SBQueue &
SBQueue::operator = (const lldb::SBQueue &rhs)
{
    m_opaque_sp = rhs.m_opaque_sp;
    return *this;
}

SBQueue::~SBQueue()
{
}

bool
SBQueue::IsValid() const
{
    bool is_valid = m_opaque_sp->IsValid ();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s", m_opaque_sp->GetQueueID(),
                    is_valid ? "true" : "false");
    return is_valid;
}


void
SBQueue::Clear ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID());
    m_opaque_sp->Clear();
}


void
SBQueue::SetQueue (const QueueSP& queue_sp)
{
    m_opaque_sp->SetQueue (queue_sp);
}

lldb::queue_id_t
SBQueue::GetQueueID () const
{
    lldb::queue_id_t qid = m_opaque_sp->GetQueueID ();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64, m_opaque_sp->GetQueueID(), (uint64_t) qid);
    return qid;
}

uint32_t
SBQueue::GetIndexID () const
{
    uint32_t index_id = m_opaque_sp->GetIndexID ();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32, m_opaque_sp->GetQueueID(), index_id);
    return index_id;
}

const char *
SBQueue::GetName () const
{
    const char *name = m_opaque_sp->GetName ();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s", m_opaque_sp->GetQueueID(), 
                     name ? name : "");
    return name;
}

uint32_t
SBQueue::GetNumThreads ()
{
    uint32_t numthreads = m_opaque_sp->GetNumThreads ();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d", m_opaque_sp->GetQueueID(), numthreads);
    return numthreads;
}

SBThread
SBQueue::GetThreadAtIndex (uint32_t idx)
{
    SBThread th = m_opaque_sp->GetThreadAtIndex (idx);
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)", m_opaque_sp->GetQueueID(), idx);
    return th;
}


uint32_t
SBQueue::GetNumPendingItems ()
{
    uint32_t pending_items = m_opaque_sp->GetNumPendingItems ();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d", m_opaque_sp->GetQueueID(), pending_items);
    return pending_items;
}

SBQueueItem
SBQueue::GetPendingItemAtIndex (uint32_t idx)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)", m_opaque_sp->GetQueueID(),  idx);
    return m_opaque_sp->GetPendingItemAtIndex (idx);
}

uint32_t
SBQueue::GetNumRunningItems ()
{
    uint32_t running_items = m_opaque_sp->GetNumRunningItems ();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d", m_opaque_sp->GetQueueID(), running_items);
    return running_items;
}

SBProcess
SBQueue::GetProcess ()
{
    return m_opaque_sp->GetProcess();
}

lldb::QueueKind
SBQueue::GetKind ()
{
    return m_opaque_sp->GetKind();
}
