//===-- 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 <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();
}
