# Generated by CodiumAI
from datetime import datetime, time, timedelta
from ipaddress import IPv4Address

import pytest

from pyadtpulse.const import (
    ADT_DEFAULT_POLL_INTERVAL,
    ADT_GATEWAY_OFFLINE_POLL_INTERVAL,
)
from pyadtpulse.gateway import ADTPulseGateway


class TestADTPulseGateway:
    # create an instance of ADTPulseGateway with default values
    def test_create_instance_with_default_values(self):
        gateway = ADTPulseGateway()
        assert gateway.manufacturer == "Unknown"
        assert gateway._status_text == "OFFLINE"
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        assert gateway._initial_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        assert gateway.model is None
        assert gateway.serial_number is None
        assert gateway.next_update == 0
        assert gateway.last_update == 0
        assert gateway.firmware_version is None
        assert gateway.hardware_version is None
        assert gateway.primary_connection_type is None
        assert gateway.broadband_connection_status is None
        assert gateway.cellular_connection_status is None
        assert gateway.cellular_connection_signal_strength == 0.0
        assert gateway.broadband_lan_ip_address is None
        assert gateway.broadband_lan_mac is None
        assert gateway.device_lan_ip_address is None
        assert gateway.device_lan_mac is None
        assert gateway.router_lan_ip_address is None
        assert gateway.router_wan_ip_address is None

    # set is_online to True and check that it returns True
    def test_set_is_online_true(self):
        gateway = ADTPulseGateway()
        gateway.is_online = True
        assert gateway.is_online is True

    # set is_online to False and check that it returns False
    def test_set_is_online_false(self):
        gateway = ADTPulseGateway()
        gateway.is_online = False
        assert gateway.is_online is False

    # set poll_interval to a valid value and check that it returns the same value
    def test_set_poll_interval_valid_value(self):
        gateway = ADTPulseGateway()
        gateway.poll_interval = 10.0
        assert gateway.poll_interval == 10.0

    # set poll_interval to None and check that it returns ADT_DEFAULT_POLL_INTERVAL
    def test_set_poll_interval_none(self):
        gateway = ADTPulseGateway()
        gateway.poll_interval = None
        assert gateway.poll_interval == ADT_DEFAULT_POLL_INTERVAL

    # set gateway attributes using set_gateway_attributes method and check that
    # they are set correctly
    def test_set_gateway_attributes(self):
        gateway = ADTPulseGateway()
        attributes = {
            "manufacturer": "ADT",
            "_status_text": "ONLINE",
            "model": "1234",
            "serial_number": "5678",
            "next_update": "Today\xa09:03\xa0AM",
            "last_update": "Yesterday\xa011:55\xa0PM",
            "firmware_version": "1.0",
            "hardware_version": "2.0",
            "primary_connection_type": "Ethernet",
            "broadband_connection_status": "Connected",
            "cellular_connection_status": "Disconnected",
            "cellular_connection_signal_strength": 3.5,
            "broadband_lan_ip_address": IPv4Address("192.168.1.1"),
            "broadband_lan_mac": "00:11:22:33:44:55",
            "device_lan_ip_address": IPv4Address("192.168.1.2"),
            "device_lan_mac": "AA:BB:CC:DD:EE:FF",
            "router_lan_ip_address": IPv4Address("192.168.1.3"),
            "router_wan_ip_address": IPv4Address("10.0.0.1"),
        }
        gateway.set_gateway_attributes(attributes)
        assert gateway.manufacturer == "ADT"
        assert gateway.model == "1234"
        assert gateway.serial_number == "5678"
        now = datetime.now()
        yesterday = now - timedelta(days=1)
        assert gateway.next_update == int(
            datetime.combine(now.date(), time(9, 3)).timestamp()
        )
        assert gateway.last_update == int(
            datetime.combine(yesterday.date(), time(23, 55)).timestamp()
        )
        assert gateway.firmware_version == "1.0"
        assert gateway.hardware_version == "2.0"
        assert gateway.primary_connection_type == "Ethernet"
        assert gateway.broadband_connection_status == "Connected"
        assert gateway.cellular_connection_status == "Disconnected"
        assert gateway.cellular_connection_signal_strength == 3.5
        assert gateway.broadband_lan_ip_address == IPv4Address("192.168.1.1")
        assert gateway.broadband_lan_mac == "00:11:22:33:44:55"
        assert gateway.device_lan_ip_address == IPv4Address("192.168.1.2")
        assert gateway.device_lan_mac == "AA:BB:CC:DD:EE:FF"
        assert gateway.router_lan_ip_address == IPv4Address("192.168.1.3")
        assert gateway.router_wan_ip_address == IPv4Address("10.0.0.1")

    # set poll_interval to a negative value and check that it raises a ValueError
    def test_set_poll_interval_negative_value(self):
        gateway = ADTPulseGateway()
        with pytest.raises(ValueError):
            gateway.poll_interval = -10.0

    # set gateway attributes with invalid IP address and check that it
    # sets the attribute to None
    def test_set_gateway_attributes_invalid_ip_address(self):
        gateway = ADTPulseGateway()
        attributes = {
            "broadband_lan_ip_address": "invalid_ip_address",
            "device_lan_ip_address": "invalid_ip_address",
            "router_lan_ip_address": "invalid_ip_address",
            "router_wan_ip_address": "invalid_ip_address",
        }
        gateway.set_gateway_attributes(attributes)
        assert gateway.broadband_lan_ip_address is None
        assert gateway.device_lan_ip_address is None
        assert gateway.router_lan_ip_address is None
        assert gateway.router_wan_ip_address is None

    # set gateway attributes with invalid datetime and check that it
    # sets the attribute to None
    def test_set_gateway_attributes_invalid_datetime(self):
        gateway = ADTPulseGateway()
        attributes = {
            "next_update": "invalid_datetime",
            "last_update": "invalid_datetime",
        }
        gateway.set_gateway_attributes(attributes)
        assert gateway.next_update is None
        assert gateway.last_update is None

    # set is_online to True when it is already True and check that it does not
    # change the status
    def test_set_is_online_true_already_true(self):
        gateway = ADTPulseGateway()
        gateway.is_online = True
        gateway.is_online = True
        assert gateway.is_online is True

    # set is_online to False when it is already False and check that it does
    # not change the status
    def test_set_is_online_false_already_false(self):
        gateway = ADTPulseGateway()
        gateway.is_online = False
        gateway.is_online = False
        assert gateway.is_online is False

    # Check that adjust_backoff_poll_interval method sets the current poll
    # interval correctly
    def test_adjust_backoff_poll_interval_fixed(self):
        gateway = ADTPulseGateway()
        gateway.poll_interval = ADT_DEFAULT_POLL_INTERVAL
        gateway.adjust_backoff_poll_interval()
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL * 2
        gateway.is_online = True
        gateway.adjust_backoff_poll_interval()
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        gateway.is_online = False
        gateway.adjust_backoff_poll_interval()
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        gateway.adjust_backoff_poll_interval()
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL * 2
        gateway.adjust_backoff_poll_interval()
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL * 4
        gateway.is_online = True
        gateway.adjust_backoff_poll_interval()
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL

    # check that is_online setter changes the poll interval correctly
    def test_is_online_setter_changes_poll_interval(self):
        gateway = ADTPulseGateway()
        gateway.is_online = True
        assert gateway._status_text == "ONLINE"
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        gateway.is_online = False
        assert gateway._status_text == "OFFLINE"
        assert gateway._current_poll_interval == ADT_GATEWAY_OFFLINE_POLL_INTERVAL

    # check that poll_interval setter changes the poll interval correctly
    def test_poll_interval_setter_changes_poll_interval(self):
        gateway = ADTPulseGateway()
        gateway.poll_interval = 60.0
        assert gateway._initial_poll_interval == 60.0
        assert gateway._current_poll_interval == 60.0
        gateway.poll_interval = None
        assert gateway._initial_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL

    # check that set_gateway_attributes method sets None for empty strings
    def test_set_gateway_attributes_sets_none_for_empty_strings(self):
        gateway = ADTPulseGateway()
        attributes = {
            "manufacturer": "",
            "model": "",
            "serial_number": "",
            "firmware_version": "",
            "hardware_version": "",
            "primary_connection_type": "",
            "broadband_connection_status": "",
            "cellular_connection_status": "",
            "broadband_lan_mac": "",
            "device_lan_mac": "",
            "router_lan_ip_address": "",
            "router_wan_ip_address": "",
        }
        gateway.set_gateway_attributes(attributes)
        assert gateway.manufacturer is None
        assert gateway.model is None
        assert gateway.serial_number is None
        assert gateway.firmware_version is None
        assert gateway.hardware_version is None
        assert gateway.primary_connection_type is None
        assert gateway.broadband_connection_status is None
        assert gateway.cellular_connection_status is None
        assert gateway.broadband_lan_mac is None
        assert gateway.device_lan_mac is None
        assert gateway.router_lan_ip_address is None
        assert gateway.router_wan_ip_address is None
        assert gateway._current_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        assert gateway._initial_poll_interval == ADT_DEFAULT_POLL_INTERVAL

    # Check that set_gateway_attributes method sets None for None values and throws an
    # exception for mandatory parameters set to None
    def test_set_gateway_attributes_sets_none_for_none_values(self):
        gateway = ADTPulseGateway()
        attributes = {
            "manufacturer": None,
            "_status_text": None,
            "_current_poll_interval": None,
            "_initial_poll_interval": None,
            "model": None,
            "serial_number": None,
            "next_update": None,
            "last_update": None,
            "firmware_version": None,
            "hardware_version": None,
            "primary_connection_type": None,
            "broadband_connection_status": None,
            "cellular_connection_status": None,
            "cellular_connection_signal_strength": None,
            "broadband_lan_ip_address": None,
            "broadband_lan_mac": None,
            "device_lan_ip_address": None,
            "device_lan_mac": None,
            "router_lan_ip_address": None,
            "router_wan_ip_address": None,
        }
        gateway.set_gateway_attributes(attributes)
        assert gateway.manufacturer is None
        assert gateway._initial_poll_interval == ADT_DEFAULT_POLL_INTERVAL
        assert gateway.model is None
        assert gateway.serial_number is None
        assert gateway.next_update is None
        assert gateway.last_update is None
        assert gateway.firmware_version is None
        assert gateway.hardware_version is None
        assert gateway.primary_connection_type is None
        assert gateway.broadband_connection_status is None
        assert gateway.cellular_connection_status is None
        assert gateway.cellular_connection_signal_strength is None
        assert gateway.broadband_lan_ip_address is None
        assert gateway.broadband_lan_mac is None
        assert gateway.device_lan_ip_address is None
        assert gateway.device_lan_mac is None
        assert gateway.router_lan_ip_address is None
        assert gateway.router_wan_ip_address is None
