#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
