#include "FunctionIndex.h"

#include <QtConcurrent/QtConcurrent>

FunctionIndex::FunctionIndex(QObject *parent)
    : QObject(parent)
{
    m_scanner = new FunctionScanner(this);
    m_watcher = new QFutureWatcher<QList<FunctionScanner::FunctionInfo>>(this);

    connect(m_watcher, &QFutureWatcher<QList<FunctionScanner::FunctionInfo>>::finished,
            this, &FunctionIndex::onScanFinished);
}

void FunctionIndex::setProjectRoot(const QString &path)
{
    m_projectRoot = path;
    m_ready       = false;
    m_index.clear();

    if (!path.isEmpty())
    {
        refresh();
    }
}

void FunctionIndex::refresh()
{
    if (m_projectRoot.isEmpty())
    {
        return;
    }

    if (m_watcher->isRunning())
    {
        m_watcher->cancel();
        m_watcher->waitForFinished();
    }

    FunctionScanner *scanner = m_scanner;
    const QString    root    = m_projectRoot;

    m_watcher->setFuture(
        QtConcurrent::run([scanner, root]()
        {
            return scanner->scanDirectory(root);
        })
    );
}

void FunctionIndex::onScanFinished()
{
    if (m_watcher->isCanceled())
    {
        return;
    }

    m_index.clear();
    const QList<FunctionScanner::FunctionInfo> all = m_watcher->result();

    for (const FunctionScanner::FunctionInfo &func : all)
    {
        const QString key = func.name.toLower();
        // Ersten Eintrag bevorzugen (globale Funktionen vor Methoden)
        if (!m_index.contains(key) || func.className.isEmpty())
        {
            m_index.insert(key, func);
        }
    }

    m_ready = true;
    emit indexReady();
}

FunctionScanner::FunctionInfo FunctionIndex::lookup(const QString &name) const
{
    return m_index.value(name.toLower(), FunctionScanner::FunctionInfo{});
}

bool FunctionIndex::isReady() const
{
    return m_ready;
}
