from datetime import timezone

from inventory_monitor.netbox import Netbox


class TestCheckProbeItemDiff:
    def _make_probe(self, **kwargs):
        class FakeProbe:
            device_descriptor = kwargs.get("device_descriptor", "dev1")
            site_descriptor = kwargs.get("site_descriptor", "site1")
            location_descriptor = kwargs.get("location_descriptor", "loc1")
            part = kwargs.get("part", "part1")
            name = kwargs.get("name", "name1")
            description = kwargs.get("description", "desc1")
            category = kwargs.get("category", "chassis")
        return FakeProbe()

    def _make_params(self, **overrides):
        params = {
            "device_descriptor": "dev1",
            "site_descriptor": "site1",
            "location_descriptor": "loc1",
            "part": "part1",
            "name": "name1",
            "description": "desc1",
            "category": "chassis",
        }
        params.update(overrides)
        return params

    def test_no_diff(self):
        probe = self._make_probe()
        params = self._make_params()
        assert Netbox._check_probe_item_diff(params, probe) is False

    def test_diff_in_name(self):
        probe = self._make_probe()
        params = self._make_params(name="different_name")
        assert Netbox._check_probe_item_diff(params, probe) is True

    def test_diff_in_category(self):
        probe = self._make_probe()
        params = self._make_params(category="module")
        assert Netbox._check_probe_item_diff(params, probe) is True


class TestSetProbeTimestamps:
    def test_creation_timestamps(self):
        params = {}
        Netbox._set_probe_timestamps(params, for_creation=True)
        assert "creation_time" in params
        assert "time" in params
        assert params["creation_time"] != params["time"]

    def test_update_timestamp(self):
        params = {}
        Netbox._set_probe_timestamps(params, for_creation=False)
        assert "time" in params
        assert "creation_time" not in params

    def test_timestamps_are_utc(self):
        params = {}
        Netbox._set_probe_timestamps(params, for_creation=True)
        # UTC ISO format contains +00:00
        assert "+00:00" in params["time"]
        assert "+00:00" in params["creation_time"]


class TestPrepareProbeParams:
    def test_basic_params(self):
        class FakeDevice:
            id = 1
            name = "router-1"
            site = None
            location = None
            device_type = None

        snmp_params = {
            "entPhysicalName": "Chassis",
            "entPhysicalModelName": "ISR4451",
            "entPhysicalSerialNum": "SN12345678",
            "entPhysicalDescr": "Cisco ISR",
            "entPhysicalClass": "chassis",
            "entPhysicalMfgName": "Cisco",
        }

        result = Netbox._prepare_probe_params(FakeDevice(), snmp_params)
        assert result["device_descriptor"] == "router-1"
        assert result["serial"] == "SN12345678"
        assert result["category"] == "chassis"
        assert result["site"] is None
        assert result["location"] is None

    def test_with_site_and_location(self):
        class FakeSite:
            id = 10
            name = "DC1"

        class FakeLocation:
            id = 20
            name = "Row A"

        class FakeDevice:
            id = 1
            name = "switch-1"
            site = FakeSite()
            location = FakeLocation()
            device_type = None

        snmp_params = {
            "entPhysicalName": "Module",
            "entPhysicalModelName": "WS-X6748",
            "entPhysicalSerialNum": "MOD12345",
            "entPhysicalDescr": "Module desc",
            "entPhysicalClass": "module",
        }

        result = Netbox._prepare_probe_params(FakeDevice(), snmp_params)
        assert result["site"] == {"id": 10}
        assert result["site_descriptor"] == "DC1"
        assert result["location"] == {"id": 20}
        assert result["location_descriptor"] == "Row A"
