import pytest
from devolo_home_control_api.devices.zwave import Zwave
from devolo_home_control_api.properties.binary_switch_property import BinarySwitchProperty


class TestZwave:

    @pytest.mark.usefixtures("home_control_instance")
    @pytest.mark.usefixtures("mock_mprmrest__extract_data_from_element_uid")
    @pytest.mark.usefixtures("mock_get_zwave_products")
    def test_get_property(self, mydevolo):
        device = Zwave(mydevolo_instance=mydevolo, **self.devices['mains']['properties'])

        device.binary_switch_property = {}
        element_uid = f"devolo.BinarySwitch:{self.devices['mains']['uid']}"
        device.binary_switch_property[element_uid] = BinarySwitchProperty(
            element_uid=element_uid,
            setter=lambda uid,
            state: None,
            state=self.devices['mains']['properties']['state'],
            enabled=self.devices['mains']['properties']['guiEnabled'])

        assert isinstance(device.get_property("binary_switch")[0], BinarySwitchProperty)

    @pytest.mark.usefixtures("mock_mydevolo__call")
    @pytest.mark.usefixtures("mock_get_zwave_products")
    def test_get_property_invalid(self, mydevolo):
        device = Zwave(mydevolo_instance=mydevolo, **self.devices['mains']['properties'])
        with pytest.raises(AttributeError):
            device.get_property("binary_switch")

    @pytest.mark.usefixtures("mock_mydevolo__call")
    @pytest.mark.usefixtures("mock_get_zwave_products")
    def test_battery_level(self, mydevolo):
        device = Zwave(mydevolo_instance=mydevolo, **self.devices['remote'])
        assert device.battery_level == self.devices['remote']['batteryLevel']

    @pytest.mark.usefixtures("mock_mydevolo__call")
    @pytest.mark.usefixtures("mock_get_zwave_products")
    def test_device_online_state_state(self, mydevolo):
        device = Zwave(mydevolo_instance=mydevolo, **self.devices['ambiguous_2'])
        assert device.status == 1

        device = Zwave(mydevolo_instance=mydevolo, **self.devices['mains']['properties'])
        assert device.status == 2

        device = Zwave(mydevolo_instance=mydevolo, **self.devices['ambiguous_1'])
        assert device.status not in [1, 2]

    @pytest.mark.usefixtures("mock_get_zwave_products")
    def test_in_online_online(self, mydevolo):
        device = Zwave(mydevolo_instance=mydevolo, **self.devices['mains']['properties'])
        assert device.is_online()

    @pytest.mark.usefixtures("mock_get_zwave_products")
    def test_in_online_offline(self, mydevolo):
        device = Zwave(mydevolo_instance=mydevolo, **self.devices['offline'])
        assert not device.is_online()

    @pytest.mark.usefixtures("mock_mydevolo__call")
    def test_get_zwave_info(self, mydevolo):
        device = Zwave(mydevolo_instance=mydevolo, **self.devices['mains']['properties'])
        device.get_zwave_info()
        assert device.brand == self.devices['mains']['brand']
