# (c) cavaliba.com - tests / ipam / ip_view()

from django.test import TestCase, override_settings
from django.urls import reverse

import app_home.cache as cache
from tests import helper


@override_settings(CAVALIBA_AUTH_MODE="unittest")
class IpViewTest(TestCase):
    def setUp(self):
        cache.clear()
        helper.add_admin_user(login="unittest")

        helper.add_schema(
            classname="ipam_subnet",
            options={"keyname_mode": "edit"},
            field_definition={
                "description": {"dataformat": "string", "displayname": "Description"},
                "subnet": {
                    "dataformat": "ipv4",
                    "dataformat_ext": "subnet strict",
                    "displayname": "Subnet",
                },
            },
        )
        helper.add_schema(
            classname="ipam_vlan",
            field_definition={
                "description": {"dataformat": "string", "displayname": "Description"},
                "vlan_id": {"dataformat": "int", "displayname": "VLAN ID"},
                "subnet": {
                    "dataformat": "schema",
                    "dataformat_ext": "ipam_subnet",
                    "cardinal_max": 0,
                    "displayname": "Subnet",
                },
            },
        )
        helper.add_schema(
            classname="ipam_ip",
            options={"keyname_mode": "edit"},
            field_definition={
                "description": {"dataformat": "string", "displayname": "Description"},
            },
        )
        helper.add_schema(
            classname="ipviewtest",
            field_definition={"ip_address": {"dataformat": "ipv4", "displayname": "IP"}},
        )

        helper.add_instance(
            classname="ipam_subnet",
            keyname="192.0.2.0/28",
            fields={"subnet": "192.0.2.0/28", "description": "test subnet"},
        )
        helper.add_instance(
            classname="ipam_vlan",
            keyname="TESTVLAN",
            fields={"displayname": "Test VLAN", "vlan_id": 10, "subnet": ["192.0.2.0/28"]},
        )
        helper.add_instance(
            classname="ipviewtest", keyname="host1", fields={"ip_address": "192.0.2.5"}
        )

    def test_valid_ip_returns_200_with_related_object(self):
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "192.0.2.5"})
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "192.0.2.5")
        self.assertContains(response, "host1")

    def test_ip_shows_containing_subnet_and_vlan_links(self):
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "192.0.2.5"})
        self.assertContains(response, "192.0.2.0/28")
        self.assertContains(response, "Test VLAN")

    def test_page_title_includes_ip_and_description(self):
        helper.add_instance(
            classname="ipam_ip", keyname="192.0.2.5", fields={"description": "gateway"}
        )
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "192.0.2.5"})
        self.assertContains(response, "IPAM - IP - 192.0.2.5 - gateway")

    def test_no_search_bar_on_result_page(self):
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "192.0.2.5"})
        self.assertNotContains(response, 'name="query"')

    def test_curated_ipam_ip_shows_edit_link(self):
        helper.add_instance(
            classname="ipam_ip", keyname="192.0.2.5", fields={"description": "gateway"}
        )
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "192.0.2.5"})
        self.assertContains(response, "gateway")
        self.assertContains(response, "/data/private/instance/edit/")

    def test_unknown_ip_offers_create_link_prefilled_with_keyname(self):
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "203.0.113.9"})
        self.assertContains(response, "/data/private/schema/new/ipam_ip?keyname=203.0.113.9")


@override_settings(CAVALIBA_AUTH_MODE="unittest")
class IpViewCreateLinkPermissionTest(TestCase):
    """CAVALIBA_AUTH_MODE="unittest" always acts as the user literally named "unittest"
    (app_data/aaa.py) - so unlike IpViewTest above, this user is a limited, non-admin
    user so has_create_permission("ipam_ip") is genuinely false."""

    def setUp(self):
        cache.clear()
        helper.add_user_with_perm(login="unittest", perms=["p_ipam_access", "p_ipam_read"])
        helper.add_schema(
            classname="ipam_ip",
            options={"keyname_mode": "edit"},
            field_definition={
                "description": {"dataformat": "string", "displayname": "Description"},
            },
        )

    def test_create_link_hidden_without_create_permission(self):
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "203.0.113.9"})
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, "/data/private/schema/new/ipam_ip")

    def test_ipv6_shows_error(self):
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "::1"})
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "IPv6")

    def test_invalid_ip_shows_error(self):
        response = self.client.get(reverse("app_ipam:ip_view"), {"ip": "not-an-ip"})
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "valid IPv4")
