"""Tests for command parsing and application."""

from __future__ import annotations

import unittest

from control.commands import CommandError, apply_command
from control.config import ControlConfig
from control.state import ControlState


class TestCommands(unittest.TestCase):
    def setUp(self) -> None:
        self.cfg = ControlConfig()
        self.state = ControlState(target_f=100.0)

    def test_set_heat_mode_sleep_clears_startup_error(self) -> None:
        self.state.heat_phase = "error_startup"
        self.state.error = {"code": "startup_failed", "detail": "x"}
        apply_command(
            self.state,
            self.cfg,
            {"op": "set_heat_mode", "args": {"mode": "sleep"}, "id": "1"},
        )
        self.assertEqual(self.state.heat_mode, "sleep")
        self.assertIsNone(self.state.error)
        self.assertEqual(self.state.heat_phase, "idle")

    def test_target_clamped(self) -> None:
        self.cfg.target_f_max = 110
        apply_command(
            self.state,
            self.cfg,
            {"op": "set_target_temp", "args": {"target_f": 200}},
        )
        self.assertEqual(self.state.target_f, 110)

    def test_increment_decrement(self) -> None:
        apply_command(self.state, self.cfg, {"op": "target_temp_increment", "args": {}})
        self.assertEqual(self.state.target_f, 101)
        apply_command(self.state, self.cfg, {"op": "target_temp_decrement", "args": {"delta_f": 2}})
        self.assertEqual(self.state.target_f, 99)

    def test_invalid_op(self) -> None:
        with self.assertRaises(CommandError):
            apply_command(self.state, self.cfg, {"op": "nope"})


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