"""Per-track steady-state summary (docs/rules/db-sql-schema.md section 5).

Both engines must produce identical values: SQLite calls this function
during load (task 05); the PostgreSQL materialized view (task 06)
implements the same three steps in SQL. Plain sequential float arithmetic
keeps results within the 1e-9 checksum tolerance across implementations.
"""

from __future__ import annotations

import math

TAIL_START_CYCLE = 501  # steady-state proxy window: cycles 501..N


def summarize_track(cofs: list[float]) -> tuple[float, float, int]:
	"""Return (cof_ss_mean, cof_ss_std, run_in_cycles) for cofs[i] = cof at cycle i+1."""
	n = len(cofs)
	tail = cofs[TAIL_START_CYCLE - 1:]
	m = _mean(tail)
	s = _stddev_pop(tail, m)

	run_in = TAIL_START_CYCLE - 1  # fallback when no cycle enters the 2-sigma band
	band = 2.0 * s
	for c in range(1, n + 1):
		if abs(cofs[c - 1] - m) < band:
			run_in = c
			break

	ss = cofs[run_in:]  # cycles strictly greater than run_in
	ss_mean = _mean(ss)
	ss_std = _stddev_pop(ss, ss_mean)
	return ss_mean, ss_std, run_in


def _mean(values: list[float]) -> float:
	total = 0.0
	for v in values:
		total += v
	return total / len(values)


def _stddev_pop(values: list[float], mean: float) -> float:
	acc = 0.0
	for v in values:
		d = v - mean
		acc += d * d
	return math.sqrt(acc / len(values))
