#include "rive/profiler/rive_profile.hpp"
#include "rive/core/vector_binary_writer.hpp"
#include "rive/artboard.hpp"
#include "rive/artboard_host.hpp"
#include "rive/artboard_component_list.hpp"
#include "rive/nested_artboard.hpp"
#include <algorithm>

#ifdef RIVE_MICROPROFILE
#include "rive/profiler/microprofile_emscripten.h"
#include "microprofile.h"

namespace
{
void writeInt64(rive::VectorBinaryWriter& writer, int64_t value)
{
    writer.write(reinterpret_cast<const uint8_t*>(&value), sizeof(value));
}

void writeProfileHeader(rive::VectorBinaryWriter& writer)
{
    MicroProfile* pState = MicroProfileGet();
    writer.write((uint32_t)0x52505246); // "RPRF" magic
    writer.write((uint32_t)2);          // version 2
    writeInt64(writer, MicroProfileTicksPerSecondCpu());
    writer.writeVarUint(pState->nTotalTimers);
    for (uint32_t i = 0; i < pState->nTotalTimers; i++)
    {
        const auto& info = pState->TimerInfo[i];
        writer.write(std::string(info.pName));
        writer.write((uint32_t)info.nGroupIndex);
        writer.write((uint32_t)info.nColor);
    }
    writer.writeVarUint(pState->nGroupCount);
    for (uint32_t i = 0; i < pState->nGroupCount; i++)
    {
        writer.write(std::string(pState->GroupInfo[i].pName));
    }
}

void writeFrameEvents(rive::VectorBinaryWriter& writer,
                      MicroProfile* pState,
                      uint32_t frameIndex,
                      uint32_t nextFrameIndex)
{
    const MicroProfileFrameState& frame = pState->Frames[frameIndex];
    const MicroProfileFrameState& nextFrame = pState->Frames[nextFrameIndex];

    std::vector<uint8_t> payload;
    rive::VectorBinaryWriter pw(&payload);
    writeInt64(pw, frame.nFrameStartCpu);
    writeInt64(pw, nextFrame.nFrameStartCpu);
    uint32_t totalEvents = 0;
    for (uint32_t threadIdx = 0; threadIdx < MICROPROFILE_MAX_THREADS;
         threadIdx++)
    {
        MicroProfileThreadLog* pLog = pState->Pool[threadIdx];
        if (!pLog)
            continue;
        uint32_t logStart = frame.nLogStart[threadIdx];
        uint32_t logEnd = nextFrame.nLogStart[threadIdx];
        if (logEnd >= logStart)
            totalEvents += (logEnd - logStart);
        else
            totalEvents += (MICROPROFILE_BUFFER_SIZE - logStart) + logEnd;
    }
    pw.writeVarUint(totalEvents);
    for (uint32_t threadIdx = 0; threadIdx < MICROPROFILE_MAX_THREADS;
         threadIdx++)
    {
        MicroProfileThreadLog* pLog = pState->Pool[threadIdx];
        if (!pLog)
            continue;
        uint32_t logStart = frame.nLogStart[threadIdx];
        uint32_t logEnd = nextFrame.nLogStart[threadIdx];
        for (uint32_t k = logStart; k != logEnd;
             k = (k + 1) % MICROPROFILE_BUFFER_SIZE)
        {
            MicroProfileLogEntry entry = pLog->Log[k];
            uint64_t nType = MicroProfileLogType(entry);
            uint64_t nTimerIndex = MicroProfileLogTimerIndex(entry);
            int64_t nTick =
                MicroProfileLogTickDifference(frame.nFrameStartCpu, entry);
            uint8_t eventType = (nType == MP_LOG_ENTER)   ? 0
                                : (nType == MP_LOG_LEAVE) ? 1
                                                          : 2;
            pw.write(eventType);
            pw.writeVarUint((uint32_t)nTimerIndex);
            writeInt64(pw, nTick);
        }
    }

    writer.write((uint8_t)0x01);
    writer.writeVarUint(static_cast<uint32_t>(payload.size()));
    writer.write(payload.data(), payload.size());
}
} // namespace
#endif

namespace rive
{

RiveProfile& RiveProfile::instance()
{
    static RiveProfile s_instance;
    return s_instance;
}

void RiveProfile::init()
{
#ifdef RIVE_MICROPROFILE
    MicroProfileSetEnableAllGroups(true);
    MicroProfileSetForceEnable(true);
    MicroProfileOnThreadCreate("MainThread");
    MicroProfileInit();
#endif
}

void RiveProfile::frame()
{
#ifdef RIVE_MICROPROFILE
    // Frame is typically a no-op at start of loop; MicroProfile tracks
    // internally
#endif
}

void RiveProfile::endFrame()
{
#ifdef RIVE_MICROPROFILE
    if (m_profilingActive)
    {
        MicroProfileFlip();
    }
#endif
}

void RiveProfile::start()
{
#ifdef RIVE_MICROPROFILE
    m_profilingActive = true;
    m_headerWritten = false;
    m_lastFlushedFrameIndex = 0;
    m_stringTable.clear();
    m_stringList.clear();
    MicroProfileSetEnableAllGroups(true);
    MicroProfileSetForceEnable(true);
    MicroProfile* pState = MicroProfileGet();
    if (pState != nullptr)
    {
        // Skip the boundary frame. nFramePutIndex only advances on flip, and we
        // only flip while profiling is active, so the frame slot at
        // nFramePutIndex holds a stale tick from before this session (the
        // MicroProfileInit tick, or the last flip of a previous session). Its
        // "duration" would be the idle gap before start() rather than a real
        // frame, producing an absurd spike. Start one frame later so the first
        // emitted frame is bounded by two in-session flips.
        m_lastFlushedFrameIndex = pState->nFramePutIndex + 1;
    }
#endif
}

void RiveProfile::stop()
{
#ifdef RIVE_MICROPROFILE
    m_profilingActive = false;
    MicroProfileSetForceEnable(false);
#endif
}

bool RiveProfile::isActive() const
{
#ifdef RIVE_MICROPROFILE
    return m_profilingActive;
#else
    return false;
#endif
}

void RiveProfile::flushFrameDataTo(std::vector<uint8_t>& buffer)
{
#ifdef RIVE_MICROPROFILE
    MicroProfile* pState = MicroProfileGet();
    if (pState == nullptr)
        return;
    VectorBinaryWriter writer(&buffer);
    if (!m_headerWritten)
    {
        writeProfileHeader(writer);
        m_headerWritten = true;
    }
    uint64_t currentFrameIndex = pState->nFramePutIndex;
    const uint32_t GPU_DELAY = MICROPROFILE_GPU_FRAME_DELAY + 1;
    if (currentFrameIndex <= m_lastFlushedFrameIndex + GPU_DELAY)
        return;
    uint64_t endFrameIndex = currentFrameIndex - GPU_DELAY;
    uint64_t maxHistory = MICROPROFILE_MAX_FRAME_HISTORY - GPU_DELAY - 2;
    if (endFrameIndex - m_lastFlushedFrameIndex > maxHistory)
    {
        m_lastFlushedFrameIndex = endFrameIndex - maxHistory;
    }
    // Emit every real frame, however slow. The whole point of the profiler is
    // to measure performance across devices, so a genuinely slow frame (even
    // hundreds of ms on weak hardware) MUST reach the tool - we do not drop by
    // magnitude here. The only frames skipped are corrupt ones: a negative
    // duration means the two frame-start slots are out of order (e.g. a stale
    // ring slot that hasn't been written this session). Pauses/stalls (which
    // look like a single very long frame) are left in the stream and flagged
    // downstream so they can be shown without wrecking the aggregates.
    for (uint64_t frameIdx = m_lastFlushedFrameIndex; frameIdx < endFrameIndex;
         frameIdx++)
    {
        uint32_t ringIdx =
            static_cast<uint32_t>(frameIdx % MICROPROFILE_MAX_FRAME_HISTORY);
        uint32_t nextRingIdx = static_cast<uint32_t>(
            (frameIdx + 1) % MICROPROFILE_MAX_FRAME_HISTORY);
        int64_t durationTicks = pState->Frames[nextRingIdx].nFrameStartCpu -
                                pState->Frames[ringIdx].nFrameStartCpu;
        if (durationTicks < 0)
        {
            continue;
        }
        writeFrameEvents(writer, pState, ringIdx, nextRingIdx);
    }
    m_lastFlushedFrameIndex = endFrameIndex;
#endif
}

#ifdef RIVE_MICROPROFILE
namespace
{
std::vector<ArtboardPathSegment> buildArtboardPath(Artboard* artboard,
                                                   RiveProfile* profile)
{
    std::vector<ArtboardPathSegment> pathSegments;
    if (artboard == nullptr || profile == nullptr)
    {
        return pathSegments;
    }
    Artboard* current = artboard;
    while (ArtboardHost* host = current->host())
    {
        ArtboardPathSegment segment;
        if (host->type() == NestedArtboardBase::typeKey)
        {
            auto na = static_cast<NestedArtboard*>(host);
            segment.type = 0;
            segment.nameId = profile->resolveStringId(na->name());
            segment.index = -1;
        }
        else if (host->type() == ArtboardComponentListBase::typeKey)
        {
            auto acl = static_cast<ArtboardComponentList*>(host);
            segment.type = 1;
            segment.nameId = profile->resolveStringId(acl->name());
            segment.index = current->isInstance()
                                ? acl->indexOfArtboardInstance(
                                      static_cast<ArtboardInstance*>(current))
                                : -1;
        }
        else
        {
            break;
        }
        pathSegments.push_back(segment);
        ArtboardPathSegment abSegment;
        abSegment.type = 0;
        abSegment.nameId = profile->resolveStringId(current->name());
        abSegment.index = -1;
        pathSegments.push_back(abSegment);
        current = host->parentArtboard();
        if (current == nullptr)
        {
            break;
        }
    }
    std::reverse(pathSegments.begin(), pathSegments.end());
    return pathSegments;
}
} // namespace
#endif

void RiveProfile::recordTransition(std::string artboardName,
                                   std::string smName,
                                   std::string layerName,
                                   std::string fromStateName,
                                   std::string toStateName,
                                   Artboard* artboardForPath)
{
#ifdef RIVE_MICROPROFILE
    if ((m_logFlags & ProfileLogTransitionRecords) == 0)
        return;
    if (!isActive() || !m_flushCallback)
        return;
    TransitionRecord rec;
    rec.artboardId = resolveStringId(artboardName);
    rec.smId = resolveStringId(smName);
    rec.layerId = resolveStringId(layerName);
    rec.fromStateId = resolveStringId(fromStateName);
    rec.toStateId = resolveStringId(toStateName);
    rec.tick = MP_TICK();
    if (artboardForPath != nullptr)
        rec.path = buildArtboardPath(artboardForPath, this);
    m_transitionRecords.push_back(std::move(rec));
#endif
}

uint32_t RiveProfile::resolveStringId(const std::string& str)
{
#ifdef RIVE_MICROPROFILE
    auto it = m_stringTable.find(str);
    if (it != m_stringTable.end())
    {
        return it->second;
    }
    const uint32_t id = static_cast<uint32_t>(m_stringList.size());
    m_stringTable[str] = id;
    m_stringList.push_back(str);
    return id;
#else
    (void)str;
    return 0;
#endif
}

const std::vector<std::string>& RiveProfile::getStringTable() const
{
    return m_stringList;
}

void RiveProfile::setFlushCallback(FlushCallback callback)
{
    m_flushCallback = std::move(callback);
}

void RiveProfile::flushTransitionRecords()
{
    if (m_flushCallback && !m_transitionRecords.empty())
    {
        m_flushCallback(m_transitionRecords);
    }
    m_transitionRecords.clear();
}

void RiveProfile::recordListenerPerformChange(std::string artboardName,
                                              std::string smName,
                                              std::string listenerName,
                                              uint32_t listenerType,
                                              uint32_t hitEvent,
                                              uint32_t pointerId)
{
#ifdef RIVE_MICROPROFILE
    if ((m_logFlags & ProfileLogListenerPerformChanges) == 0)
        return;
    if (!isActive() || !m_listenerPerformChangeFlushCallback)
        return;
    ListenerPerformChangeRecord rec;
    rec.artboardId = resolveStringId(artboardName);
    rec.smId = resolveStringId(smName);
    rec.listenerNameId = resolveStringId(listenerName);
    rec.listenerType = listenerType;
    rec.hitEvent = hitEvent;
    rec.pointerId = pointerId;
    rec.tick = MP_TICK();
    m_listenerPerformChangeRecords.push_back(std::move(rec));
#else
    (void)artboardName;
    (void)smName;
    (void)listenerName;
    (void)listenerType;
    (void)hitEvent;
    (void)pointerId;
#endif
}

void RiveProfile::setListenerPerformChangeFlushCallback(
    ListenerPerformChangeFlushCallback callback)
{
    m_listenerPerformChangeFlushCallback = std::move(callback);
}

void RiveProfile::flushListenerPerformChangeRecords()
{
    if (m_listenerPerformChangeFlushCallback &&
        !m_listenerPerformChangeRecords.empty())
    {
        m_listenerPerformChangeFlushCallback(m_listenerPerformChangeRecords);
    }
    m_listenerPerformChangeRecords.clear();
}

} // namespace rive
