#!/usr/bin/env python3
"""Per-push() latency of a streaming session.

Builds a ~2 KB text (with PII spread through it) and pushes it in 8-character
fragments through engine.create_streaming_session(block_on_fatal=False), so the
stream is never halted and every fragment is processed. Repeats the full
stream REPEATS times (fresh session each time) after one warm-up stream.
"""
import time

from helixor_runtime import HelixorEngine

from _common import PAYLOADS, environment, summarize

FRAGMENT = 8
TARGET_BYTES = 2048
REPEATS = 20


def build_text() -> str:
    parts, n = [], 0
    i = 0
    while n < TARGET_BYTES:
        p = PAYLOADS[i % len(PAYLOADS)] + " "
        parts.append(p)
        n += len(p)
        i += 1
    return "".join(parts)[:TARGET_BYTES]


def run_stream(engine: HelixorEngine, text: str, times: list[int] | None) -> int:
    session = engine.create_streaming_session(lookahead_chars=28, block_on_fatal=False)
    clock = time.perf_counter_ns
    emitted = 0
    for k in range(0, len(text), FRAGMENT):
        frag = text[k:k + FRAGMENT]
        t0 = clock()
        out = session.push(frag)
        dt = clock() - t0
        if times is not None:
            times.append(dt)
        emitted += len(out)
    emitted += len(session.flush())
    return emitted


def main() -> None:
    print(environment())
    engine = HelixorEngine()
    text = build_text()
    run_stream(engine, text, None)  # warm-up
    times: list[int] = []
    stream_ns: list[int] = []
    for _ in range(REPEATS):
        t0 = time.perf_counter_ns()
        run_stream(engine, text, times)
        stream_ns.append(time.perf_counter_ns() - t0)
    print(f"text={len(text)} bytes fragment={FRAGMENT} chars pushes/stream={len(text) // FRAGMENT} streams={REPEATS}")
    summarize("push() wall clock", times)
    summarize("whole 2 KB stream (all pushes + flush)", stream_ns, unit="ms")


if __name__ == "__main__":
    main()
