#include "rive/watermark.hpp"

#include "rive/animation/state_machine_instance.hpp"
#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/layout.hpp"
#include "rive/renderer.hpp"
#include "rive/factory.hpp"

#include <chrono>

using namespace rive;

namespace
{
// A watermark whose state machine never settles (it loops, or rests in a state
// with a looping animation) would otherwise hold the user's file hostage. Cap
// how long the pre-roll can run.
constexpr float watermarkMaxSeconds = 10.0f;

// How far ahead of the wall clock the pre-roll's *total* consumption may run
// and still be taken at face value. Wide enough for clock jitter and for the
// gap between a host measuring its frame time and calling us, narrow enough
// that it can't hide a frame's worth of fast-forward. Cumulative, not per
// call -- see clampElapsed.
constexpr float watermarkClockToleranceSeconds = 0.004f;

// No single frame may carry the watermark further than this, whichever clock
// the delta came from. Stops a stall, a breakpoint, or a backgrounded tab from
// resuming into a leap that swallows the pre-roll whole.
constexpr float watermarkMaxFrameSeconds = 0.25f;

// The pre-roll is played against solid black, so the watermark reads the same
// regardless of what the file behind it looks like.
constexpr ColorInt watermarkBackdropColor = 0xFF000000;

// steady_clock, not high_resolution_clock: the latter aliases the adjustable
// wall clock on some standard libraries, and this clock is what stops the
// pre-roll being seeked past. A clock that can be set backwards would hand
// back a negative delta and rewind the watermark.
int64_t nowMicros()
{
  return std::chrono::duration_cast<std::chrono::microseconds>(
             std::chrono::steady_clock::now().time_since_epoch())
      .count();
}
} // namespace

Watermark::Watermark(
    std::unique_ptr<ArtboardInstance> artboard,
    std::unique_ptr<StateMachineInstance> stateMachine)
    : m_artboard(std::move(artboard))
    , m_stateMachine(std::move(stateMachine))
    , m_lastTimeMicros(nowMicros())
{
  // The host's own frame origin is applied by whoever draws us, so the
  // watermark's content sits at its own (0, 0) and we align from there.
  m_artboard->frameOrigin(false);
}

Watermark::~Watermark() {}

float Watermark::clampElapsed(float elapsedSeconds)
{
  if (elapsedSeconds < 0.0f)
  {
    return 0.0f;
  }

  if (File::deterministicMode)
  {
    // The host owns the timeline: goldens, silvers and offline renders step
    // at whatever cadence they like and there is no wall clock to measure
    // them against. Neither guard below applies.
    return elapsedSeconds;
  }

  int64_t now = nowMicros();
  float wallSeconds = (float)(now - m_lastTimeMicros) / 1000000.0f;
  m_lastTimeMicros = now;
  if (wallSeconds < 0.0f)
  {
    // steady_clock should never go backwards; if a platform's does, treat
    // it as no time passing rather than letting it unwind the pre-roll.
    wallSeconds = 0.0f;
  }

  // Credit at most one frame's worth of real time per call, the same ceiling
  // a single advance may consume. Banking the whole gap let idle time be
  // spent all at once: an instance left alone for ten seconds -- a
  // backgrounded tab, a file loaded and not yet advanced -- funded a budget
  // that forty immediate advances could drain a frame at a time, finishing
  // the pre-roll without ever showing it. Capping the credit at the same
  // ceiling as the spend makes that arithmetic impossible.
  m_wallSeconds += wallSeconds > watermarkMaxFrameSeconds
                       ? watermarkMaxFrameSeconds
                       : wallSeconds;

  // What the pre-roll may still consume without outrunning real time. The
  // budget is cumulative and the tolerance is granted against the total, not
  // per call: comparing each delta on its own let a caller spend the
  // tolerance again on every frame, so a loop of advances at or just under
  // it -- advanceAndApply(0.004f) against a tolerance of 0.004 -- was never
  // clamped and could burn the whole pre-roll in microseconds of real time.
  float budget = m_wallSeconds + watermarkClockToleranceSeconds -
                 m_elapsedSeconds;
  if (budget < 0.0f)
  {
    budget = 0.0f;
  }

  // The host's delta is honored while it fits the budget, so a host with a
  // better notion of frame time still drives playback; past that it gets
  // what has actually elapsed.
  float seconds = elapsedSeconds > budget ? budget : elapsedSeconds;
  return seconds > watermarkMaxFrameSeconds ? watermarkMaxFrameSeconds
                                            : seconds;
}

bool Watermark::advance(float elapsedSeconds)
{
  if (m_finished)
  {
    // The watermark drew its last frame already; this one is the host's.
    return false;
  }
  m_started = true;

  float seconds = clampElapsed(elapsedSeconds);

  // A settled state machine is the completion signal. Note that advancing by
  // zero always reports "keep going", so the priming zero-advance embedders
  // do right after instancing can't complete the watermark early. The
  // internal overload, because the host entry point also reports its file's
  // pending async work, and the watermark lives in the host's file: its
  // decodes in flight would hold the watermark up.
  bool more = m_stateMachine->advanceAndApply(seconds, true);
  m_elapsedSeconds += seconds;
  m_finished = !more || m_elapsedSeconds >= watermarkMaxSeconds;

  // Even the finishing frame belongs to the watermark, so its last authored
  // frame is the one on screen rather than being skipped.
  return true;
}

void Watermark::drawBackdrop(Renderer* renderer, const AABB& hostBounds)
{
  auto factory = m_artboard->factory();
  if (factory == nullptr)
  {
    return;
  }
  if (m_backdropPaint == nullptr)
  {
    m_backdropPaint = factory->makeRenderPaint();
    m_backdropPaint->style(RenderPaintStyle::fill);
    m_backdropPaint->color(watermarkBackdropColor);
  }
  if (m_backdropPath == nullptr || !(m_backdropBounds == hostBounds))
  {
    m_backdropPath = factory->makeRenderPath(hostBounds);
    m_backdropBounds = hostBounds;
  }
  if (m_backdropPaint != nullptr && m_backdropPath != nullptr)
  {
    renderer->drawPath(m_backdropPath.get(), m_backdropPaint.get());
  }
}

void Watermark::draw(Renderer* renderer, const AABB& hostBounds)
{
  // Covers the host's whole box before the watermark is fit inside it, so
  // neither the frozen host nor the letterbox around the watermark shows.
  drawBackdrop(renderer, hostBounds);

  renderer->save();
  renderer->transform(computeAlignment(
      Fit::contain,
      Alignment::center,
      hostBounds,
      m_artboard->bounds()));
  // drawInternal, not draw: whoever called us already bumped the frame id.
  m_artboard->drawInternal(renderer);
  renderer->restore();
}
