# (c) cavaliba.com - tests / app_data.ipam.ipam_refresh (EAV batch scan)

from django.test import TestCase

import app_home.cache as cache
from app_data.data import Instance
from app_data.ipam import ipam_refresh
from app_data.models import DataInstance
from tests import helper


class IpamRefreshTest(TestCase):
    def setUp(self):
        cache.clear()
        helper.add_schema(
            classname="refreshtest",
            field_definition={
                "ip_address": {"dataformat": "ipv4", "displayname": "IP"},
                "subnet_field": {
                    "dataformat": "ipv4",
                    "dataformat_ext": "subnet",
                    "displayname": "Subnet",
                },
            },
        )

    def test_backfills_entry_missing_despite_eav_already_holding_the_ip(self):
        # normal save() already auto-discovers via the real-time hook -
        # delete the resulting ipam_ip row to simulate one written before
        # that hook existed (EAV cache still has the ipv4 value either way)
        helper.add_instance(
            classname="refreshtest", keyname="host01", fields={"ip_address": "10.30.30.30"}
        )
        DataInstance.objects.filter(classname="ipam_ip", keyname="0a1e1e1e").delete()
        cache.clear()
        self.assertIsNone(Instance.from_keyname(classname="ipam_ip", keyname="0a1e1e1e"))

        count_create, count = ipam_refresh(dryrun=False)

        self.assertGreaterEqual(count_create, 1)
        inst = Instance.from_keyname(classname="ipam_ip", keyname="0a1e1e1e")
        self.assertIsNotNone(inst)
        self.assertEqual(inst.displayname, "10.30.30.30")
        self.assertTrue(inst.is_field_true("collected"))

    def test_dryrun_does_not_write(self):
        helper.add_instance(
            classname="refreshtest", keyname="host02", fields={"ip_address": "10.30.30.31"}
        )
        DataInstance.objects.filter(classname="ipam_ip", keyname="0a1e1e1f").delete()
        cache.clear()

        count_create, count = ipam_refresh(dryrun=True)

        self.assertGreaterEqual(count_create, 1)
        self.assertIsNone(Instance.from_keyname(classname="ipam_ip", keyname="0a1e1e1f"))

    def test_subnet_value_not_scanned(self):
        helper.add_instance(
            classname="refreshtest", keyname="net01", fields={"subnet_field": "10.30.40.0/24"}
        )

        ipam_refresh(dryrun=False)

        self.assertIsNone(Instance.from_keyname(classname="ipam_ip", keyname="0a1e2800"))

    def test_existing_manual_entry_not_overwritten(self):
        helper.add_instance(classname="ipam_ip", fields={"displayname": "10.30.30.32"})
        ipam_before = Instance.from_keyname(classname="ipam_ip", keyname="0a1e1e20")
        self.assertFalse(ipam_before.is_field_true("collected"))

        helper.add_instance(
            classname="refreshtest", keyname="host03", fields={"ip_address": "10.30.30.32"}
        )

        ipam_refresh(dryrun=False)

        ipam_after = Instance.from_keyname(classname="ipam_ip", keyname="0a1e1e20")
        self.assertEqual(ipam_after.id, ipam_before.id)
        self.assertFalse(ipam_after.is_field_true("collected"))
