"""Parser rámce TeltoCharge (registry 0–40) a mapování stavů na EV session logiku."""

from __future__ import annotations

import unittest

from services.telemetry_collector import (
    TELTO_REG_BLOCK_COUNT,
    TELTO_STATUS_MAP,
    parse_teltocharge_frame,
)


def _frame(**over: int) -> list[int]:
    regs = [0] * TELTO_REG_BLOCK_COUNT
    regs[0], regs[1], regs[2] = 230, 231, 229      # napětí
    regs[3], regs[4], regs[5] = 160, 158, 0        # proud ×10 A (16.0 A max)
    regs[6] = 7                                     # A – bez EV
    regs[38] = 0                                    # výkon W
    regs[39] = 0                                    # session kWh ×100
    for k, v in over.items():
        regs[int(k.lstrip("r"))] = v
    return regs


class TeltoChargeParseTests(unittest.TestCase):
    def test_charging_frame(self) -> None:
        f = parse_teltocharge_frame(_frame(r6=0, r38=10870, r39=523))
        self.assertEqual(f["status"], "charging")
        self.assertEqual(f["power_w"], 10870)
        self.assertAlmostEqual(f["session_energy_kwh"], 5.23)
        self.assertAlmostEqual(f["current_a"], 16.0)

    def test_no_ev_is_available(self) -> None:
        self.assertEqual(parse_teltocharge_frame(_frame(r6=7))["status"], "available")

    def test_all_connected_states_are_not_available(self) -> None:
        # detekce příjezdu (fn_ev_session_transition) stojí na ≠ 'available'
        for raw, mapped in TELTO_STATUS_MAP.items():
            if raw == 7:
                continue
            self.assertNotEqual(mapped, "available", f"EVSE status {raw}")

    def test_unknown_raw_status(self) -> None:
        self.assertEqual(parse_teltocharge_frame(_frame(r6=42))["status"], "unknown")

    def test_error_bits_passthrough(self) -> None:
        f = parse_teltocharge_frame(_frame(r6=8, r35=0b10000))
        self.assertEqual(f["status"], "faulted")
        self.assertEqual(f["error_bits"], 16)

    def test_short_frame_raises(self) -> None:
        with self.assertRaises(ValueError):
            parse_teltocharge_frame([0] * 10)


if __name__ == "__main__":
    unittest.main()
