from inventory_monitor.invmon import InventoryMonitor
from inventory_monitor.models import AppConfig


def _make_item(serial, class_name, model=""):
    return {
        "entPhysicalSerialNum": serial,
        "entPhysicalClass": class_name,
        "entPhysicalModelName": model,
        "entPhysicalDescr": "",
        "entPhysicalName": "",
    }


class TestPrepareDeviceSnInventory:
    def setup_method(self):
        self.monitor = InventoryMonitor(config=AppConfig())

    def test_basic_grouping(self):
        items = [
            _make_item("SN001", "chassis"),
            _make_item("SN002", "module"),
        ]
        result = self.monitor.prepare_device_sn_inventory(items)
        assert "SN001" in result
        assert "SN002" in result

    def test_priority_override(self):
        items = [
            _make_item("SN001", "sensor"),
            _make_item("SN001", "chassis"),
        ]
        result = self.monitor.prepare_device_sn_inventory(items)
        assert result["SN001"]["entPhysicalClass"] == "chassis"

    def test_lower_priority_does_not_override(self):
        items = [
            _make_item("SN001", "chassis"),
            _make_item("SN001", "fan"),
        ]
        result = self.monitor.prepare_device_sn_inventory(items)
        # chassis has higher priority, but fan is processed after chassis
        # in the priority list, so fan actually overwrites... let's check actual behavior
        # Priority order: fan comes before chassis, so chassis overwrites fan
        assert result["SN001"]["entPhysicalClass"] == "chassis"

    def test_model_excludes(self):
        cfg = AppConfig(model_name_excludes=["EXCLUDED_MODEL"])
        monitor = InventoryMonitor(config=cfg)
        items = [
            _make_item("SN001", "chassis", model="EXCLUDED_MODEL"),
            _make_item("SN002", "module", model="GOOD_MODEL"),
        ]
        result = monitor.prepare_device_sn_inventory(items)
        assert "SN001" not in result
        assert "SN002" in result

    def test_empty_inventory(self):
        result = self.monitor.prepare_device_sn_inventory([])
        assert result == {}

    def test_unrecognized_class_still_included(self):
        items = [_make_item("SN001", "unknownClass")]
        result = self.monitor.prepare_device_sn_inventory(items)
        assert "SN001" in result


class TestProcessDevice:
    def test_no_primary_ip(self):
        class FakeDevice:
            name = "test-device"
            primary_ip4 = None
            platform = None

        monitor = InventoryMonitor(config=AppConfig())
        dev, result = monitor.process_device(FakeDevice())
        assert result["error"] is True
        assert result["inventory"] == []
