"""Tests for register parsers."""

from aiovictron.registers.base import RegisterDefinition, RegisterType
from aiovictron.registers.solar_charger import SolarChargerParser
from aiovictron.registers.system import SystemParser
from aiovictron.registers.vebus import VEBusParser


class TestRegisterDefinition:
    def test_defaults(self):
        reg = RegisterDefinition("test", 100)
        assert reg.register_type == RegisterType.UINT16
        assert reg.scale == 1
        assert reg.count == 1

    def test_int16(self):
        reg = RegisterDefinition("test", 100, RegisterType.INT16, scale=10)
        assert reg.register_type == RegisterType.INT16
        assert reg.scale == 10


class TestSystemParser:
    def setup_method(self):
        self.parser = SystemParser()

    def test_device_type(self):
        assert self.parser.device_type == "system"

    def test_register_count(self):
        assert len(self.parser.registers) == 8

    def test_parse_real_values(self):
        """Test parsing with actual values from Cerbo GX probe."""
        register_map = {
            817: 0,       # ac_consumption_l1 (UINT16)
            820: 0,       # grid_power_l1 (INT16)
            840: 133,     # battery_voltage /10 = 13.3V
            841: 0xFFFB,  # battery_current /10 = -0.5A (signed: -5)
            842: 0xFFFA,  # battery_power = -6W (signed: -6)
            843: 90,      # battery_soc = 90%
            844: 0,       # battery_state = idle
            850: 4,       # pv_power = 4W
        }
        result = self.parser.parse(register_map)
        assert result["battery_voltage"] == 13.3
        assert result["battery_current"] == -0.5
        assert result["battery_power"] == -6.0
        assert result["battery_soc"] == 90.0
        assert result["pv_power"] == 4.0
        assert result["ac_consumption_l1"] == 0.0
        assert result["grid_power_l1"] == 0.0

    def test_register_ranges_avoid_gap(self):
        """Verify system registers split around the 847-849 gap."""
        ranges = self.parser.register_ranges
        # Should have 3 blocks: 817-820, 840-844, 850
        assert len(ranges) >= 2
        # No single block should span 817-850
        for start, count in ranges:
            assert count <= 15, f"Block too large: {start}-{start+count}"


class TestSolarChargerParser:
    def setup_method(self):
        self.parser = SolarChargerParser()

    def test_device_type(self):
        assert self.parser.device_type == "solar_charger"

    def test_register_count(self):
        assert len(self.parser.registers) == 8

    def test_parse_real_values(self):
        """Test parsing with actual values from Cerbo GX probe."""
        register_map = {
            771: 1327,   # battery_voltage /100 = 13.27V
            772: 252,    # battery_current /10 = 25.2A (unsigned in this case)
            775: 3,      # charger_state = bulk
            776: 4857,   # pv_voltage /100 = 48.57V
            777: 1,      # pv_current /10 = 0.1A
            784: 0,      # yield_today /10 = 0.0 kWh
            785: 161,    # max_charge_power_today = 161W
            789: 63,     # pv_power /10 = 6.3W
        }
        result = self.parser.parse(register_map)
        assert result["battery_voltage"] == 13.27
        assert result["pv_voltage"] == 48.57
        assert result["pv_current"] == 0.1
        assert result["pv_power"] == 6.3
        assert result["charger_state"] == 3.0
        assert result["max_charge_power_today"] == 161.0
        assert result["yield_today"] == 0.0


class TestVEBusParser:
    def setup_method(self):
        self.parser = VEBusParser()

    def test_device_type(self):
        assert self.parser.device_type == "vebus"

    def test_register_count(self):
        assert len(self.parser.registers) == 12

    def test_parse_real_values(self):
        """Test parsing with actual values from Cerbo GX probe."""
        register_map = {
            3: 2423,     # ac_input_voltage /10 = 242.3V
            6: 0,        # ac_input_current /10 = 0A
            9: 5010,     # ac_input_frequency /100 = 50.10Hz
            12: 0,       # ac_input_power /10 = 0W
            15: 0,       # ac_output_voltage /10 = 0V
            18: 0,       # ac_output_current /10 = 0A
            21: 4982,    # ac_output_frequency /100 = 49.82Hz
            23: 0,       # ac_output_power /10 = 0W
            26: 1327,    # battery_voltage /100 = 13.27V
            27: 0,       # battery_current /10 = 0A
            30: 0,       # battery_soc /10 = 0%
            31: 0,       # vebus_state = 0
        }
        result = self.parser.parse(register_map)
        assert result["ac_input_voltage"] == 242.3
        assert result["ac_input_frequency"] == 50.10
        assert result["ac_output_frequency"] == 49.82
        assert result["battery_voltage"] == 13.27
        assert result["vebus_state"] == 0.0

    def test_register_ranges(self):
        """VE.Bus registers span 3-31, should fit in reasonable blocks."""
        ranges = self.parser.register_ranges
        assert len(ranges) >= 1
        # Total registers read should be reasonable
        total = sum(count for _, count in ranges)
        assert total <= 35
