#pragma once
/// TRACES: AR-012, AR-013 | SR-002
///
/// FrameAnnotationFunc — project a matched frame into a per-frame annotation.
///
/// Stateless, and that is the entire point of it.
///
/// It replaces `SceneTrackerFunc`, which kept an extinction timer per actor and
/// reported an actor as visible for `extinction_sec` (57.4 s) after their last
/// detection. docs/SPEC.md specified that node's deletion -- "anneal_sec and
/// extinction_sec are deleted, not re-tuned ... SceneTrackerFunc goes with
/// them", with a removal list ending "grep for both names and expect no
/// survivors" -- and docs/requirements.md recorded both constants as Withdrawn,
/// deleted "rather than retained at zero", on the grounds that a field naming a
/// mechanism the pipeline no longer has is actively misleading. None of that
/// removal had happened. The node was still wired into both shipped pipelines
/// and still printed its timeout at every startup.
///
/// **Presence is not this node's business.** AR-012 moved it to TrackRegistry,
/// where a window is `[first_seen, last_seen]` of a track an actor owns, and
/// AR-013 ends that window at the last sighting rather than after it. A
/// keep-alive here answered the same question a second time and answered it
/// worse: it re-opened the trailing cool-down the registry exists to refuse.
///
/// What a consumer sees change: `--verbosity standard`'s `frames[].identified`
/// used to list every actor still inside the keep-alive, including ones absent
/// from the frame. It now lists what was actually matched in that frame. The
/// minimal and xray outputs are unaffected -- they were already built from
/// registry claims and never consulted this node.

#include "types.hpp"

#include <string_view>
#include <utility>

struct FrameAnnotationFunc {
    static constexpr std::string_view label() { return "frame_annotation"; }

    SceneAnnotation operator()(MatchedSceneFrame mf) {
        if (mf.source.eof) return {0.0, {}, /*eof=*/true};
        SceneAnnotation sa;
        sa.timestamp_sec     = mf.source.timestamp_sec;
        sa.visible_actors    = std::move(mf.actors);
        sa.is_cut            = mf.source.is_cut;
        sa.is_scene_boundary = mf.source.is_scene_boundary;
        sa.rgb_hist          = std::move(mf.source.rgb_hist);
        return sa;
    }
};
