"""Parquet tick cache seeder state check for heartbeat monitoring."""

from __future__ import annotations

import logging
import subprocess
import time
from pathlib import Path

logger = logging.getLogger("health-heartbeat")


def check_seeder(results: dict[str, bool | str]) -> None:
    """Parse seeder state file and check timer freshness (Issue #270).

    ``seeder_ok`` is a boolean and participates in the healthy gate.  A failing
    seeder means kintsugi falls back to Vision downloads instead of the fast
    Parquet-cached path, degrading repair throughput — important enough to flag
    as UNHEALTHY.  All other ``seeder_*`` keys are strings (informational only).
    """
    state_path = Path("/var/tmp/opendeviationbar-seeder-state.txt")
    try:
        text = state_path.read_text()
        stat = state_path.stat()
    except OSError:
        results["seeder_ok"] = False
        return

    # Parse key=value pairs (the first line is the status word, not key=value)
    kv = dict(line.split("=", 1) for line in text.strip().splitlines() if "=" in line)
    status_line = text.strip().splitlines()[0] if text.strip() else ""
    age_min = (time.time() - stat.st_mtime) / 60

    results["seeder_status"] = status_line
    results["seeder_age_min"] = f"{age_min:.0f}m"

    if status_line == "running":
        # Compute elapsed from original run-start timestamp (preserved across progress writes)
        ts_str = kv.get("timestamp", "")
        if ts_str:
            try:
                import datetime as _dt
                started = _dt.datetime.fromisoformat(ts_str)
                elapsed_min = (
                    _dt.datetime.now(_dt.timezone.utc) - started
                ).total_seconds() / 60
                results["seeder_running_min"] = f"{elapsed_min:.0f}m"
            except ValueError:
                pass
        # Progress fields written every 2 months by _seed_symbol() (new format).
        cur_sym = kv.get("current_symbol", "")
        months_done = kv.get("months_done", "")
        days_done = kv.get("days_done", "")
        if cur_sym:
            results["seeder_current_symbol"] = cur_sym
        if months_done:
            results["seeder_months_done"] = months_done
        if days_done:
            results["seeder_days_done"] = days_done
        if not cur_sym:
            # No state-file progress yet — scrape latest activity from journal
            try:
                r = subprocess.run(
                    ["journalctl", "--user", "-u", "opendeviationbar-seeder",
                     "-n", "20", "--no-pager", "--output=short-iso"],
                    capture_output=True, text=True, timeout=5, check=False,
                )
                import re as _re
                latest_month = None
                latest_seeded_line = None
                for line in reversed(r.stdout.strip().splitlines()):
                    m = _re.search(
                        r"(\w+USDT)\s+(\d{4}-\d{2}):\s+"
                        r"(?:downloading (\d+)|(\w.+?)(?:,|$))",
                        line,
                    )
                    if m:
                        latest_month = f"{m.group(1)} {m.group(2)}"
                        latest_seeded_line = line.split("] ")[-1].strip()
                        break
                if latest_month:
                    results["seeder_journal_month"] = latest_month
                if latest_seeded_line:
                    results["seeder_journal_line"] = latest_seeded_line
            except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
                pass
    else:
        results["seeder_seeded"] = kv.get("seeded", "?")
        results["seeder_elapsed"] = kv.get("elapsed_s", "?")
        # Per-symbol seeded day counts (keys like BTCUSDT_seeded=150)
        sym_counts = {k[:-7]: v for k, v in kv.items() if k.endswith("_seeded")}
        if sym_counts:
            results["seeder_symbols"] = " | ".join(
                f"{s}:{c}d" for s, c in sym_counts.items()
            )

    # Non-zero failed= means at least one symbol raised an exception this pass
    failed_str = kv.get("failed", "")
    failed = int(failed_str) if failed_str.isdigit() else 0
    if failed > 0:
        results["seeder_failed"] = str(failed)
        results["seeder_ok"] = False
        return

    # Timer freshness: >15 min = 3 consecutive 5-min triggers missed
    if age_min > 15:
        results["seeder_ok"] = False
        return

    results["seeder_ok"] = status_line in ("ok", "running")
