"""Test case for Netbox Device Creation"""

import unittest
import os
import requests
import json

HOST = os.getenv("HOST", default="localhost")
PORT = os.getenv("PORT", default="8080")
API_TOKEN = os.getenv("API_TOKEN", default="only4testingpurpose")
HEADERS = {"Authorization": f"Token {API_TOKEN}"}

#TODO: Tester ajout des dependances au config context (site, device type)
#TODO: ajout test dependance dans le config context et des differentes valeurs

class TestNetboxDeviceCreate(unittest.TestCase):
    """Test case for device creation, config context update ... """

    @classmethod
    def setUpClass(cls) -> None:
        """Will create a manufacturer, site, device role and device type"""
        response = requests.post(
            url=f"http://{HOST}:{PORT}/api/dcim/manufacturers/",
            headers=HEADERS,
            json={
                "name": "Cisco",
                "slug": "cisco"
            },
            timeout=5
        )

        """Will create a device role """

        response = requests.post(
            url=f"http://{HOST}:{PORT}/api/dcim/device-roles/",
            headers=HEADERS,
            json={
                "name": "Switch",
                "slug":"switch"
            },
            timeout=5
        )

        """ Will create a device type """
        manufacturer_id = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/manufacturers/", headers=HEADERS)
        id = json.loads(manufacturer_id.content)["results"][0]["id"]
        response = response = requests.post(
            url=f"http://{HOST}:{PORT}/api/dcim/device-types/",
            headers=HEADERS,
            json={
                "model": "WS-C2960X",
                "slug":"ws-c2960x",
                "manufacturer": id
            },
            timeout=5
        )

        """ will create a site"""
        response = requests.post(
            url=f"http://{HOST}:{PORT}/api/dcim/sites/",
            headers=HEADERS,
            json={
                "name": "ISPRA",
                "slug":"ispra"
            },
            timeout=5
        )
        site =  requests.get(url=f"http://{HOST}:{PORT}/api/dcim/sites/", headers=HEADERS)
        site_id = json.loads(site.content)["results"][0]["id"]

        device_type = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/device-types/", headers=HEADERS)
        device_type_id = json.loads(device_type.content)["results"][0]["id"]

        """ Will create a dummy config context """

        response = requests.post(
            url=f"http://{HOST}:{PORT}/api/extras/config-contexts/",
            headers=HEADERS,
            json={
                "name": "test_config_context",
                "sites": [site_id],
                "device_types": [device_type_id],
                "data": {
                    "radius_servers": [
                        "1.1.1.1",
                        "2.2.2.2"
                    ]
                }
            },
            timeout=5
        )


    @classmethod
    def tearDownClass(cls) -> None:
        """ Deleting all data from NETBOX once the all the tests finish running """

        #deleting the device

        device_id = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/devices/", headers=HEADERS)
        id = json.loads(device_id.content)["results"][0]["id"]
        response_device = requests.delete(
            url= f"http://{HOST}:{PORT}/api/dcim/devices/{id}/",
            headers=HEADERS,
            timeout=5
        )

        #deleting the device type

        device_type_id = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/device-types/", headers=HEADERS)
        id = json.loads(device_type_id.content)["results"][0]["id"]
        response_device_type = requests.delete(
            url= f"http://{HOST}:{PORT}/api/dcim/device-types/{id}/",
            headers=HEADERS,
            timeout=5
        )

        #deleting the manufacturer
        manufacturer_id = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/manufacturers/", headers=HEADERS)
        #id = json.loads(manufacturer_id.content)["id"]
        #print(json.loads(manufacturer_id.content)["results"][0]["id"])
        id = json.loads(manufacturer_id.content)["results"][0]["id"]
        #print(type(json.loads(manufacturer_id.content)["results"][0]["id"]))
        respose_manufacturer = requests.delete(
            url= f"http://{HOST}:{PORT}/api/dcim/manufacturers/{id}/",
            headers=HEADERS,
            timeout=5
        )

        # deleting the device role
        device_role_id = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/device-roles/", headers=HEADERS)
        id = json.loads(device_role_id.content)["results"][0]["id"]
        response_device_role = requests.delete(
            url= f"http://{HOST}:{PORT}/api/dcim/device-roles/{id}/",
            headers=HEADERS,
            timeout=5
        )

        # deleting the site

        site_id =  requests.get(url=f"http://{HOST}:{PORT}/api/dcim/sites/", headers=HEADERS)
        id = json.loads(site_id.content)["results"][0]["id"]
        response_site = requests.delete(
            url= f"http://{HOST}:{PORT}/api/dcim/sites/{id}/",
            headers=HEADERS,
            timeout=5
        )

        # Deleting the config context

        config_context_id = requests.get(url=f"http://{HOST}:{PORT}/api/extras/config-contexts/", headers=HEADERS)
        id = json.loads(config_context_id.content)["results"][0]["id"]
        response_config_context = requests.delete(
            url= f"http://{HOST}:{PORT}/api/extras/config-contexts/{id}/",
            headers=HEADERS,
            timeout=5
        )

    def tearDown(self) -> None:
        pass
    
    def test_device_creation(self) -> None:
        """" getting the necessary IDs """
        device_type = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/device-types/", headers=HEADERS)
        device_type_id = json.loads(device_type.content)["results"][0]["id"]

        device_role = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/device-roles/", headers=HEADERS)
        device_role_id = json.loads(device_role.content)["results"][0]["id"]

        site =  requests.get(url=f"http://{HOST}:{PORT}/api/dcim/sites/", headers=HEADERS)
        site_id = json.loads(site.content)["results"][0]["id"]

        # Creating the device

        response = response = requests.post(
            url=f"http://{HOST}:{PORT}/api/dcim/devices/",
            headers=HEADERS,
            json={
                "name": "test",
                "device_type": device_type_id,
                "role": device_role_id,
                "site": site_id,
                "status": "offline"
            },
            timeout=5
        )

        self.assertEqual(response.status_code,201)
        self.assertEqual(json.loads(response.content)["name"],"test")
        self.assertEqual(json.loads(response.content)["device_type"]["display"],"WS-C2960X")
        self.assertEqual(json.loads(response.content)["role"]["name"],"Switch")
        self.assertEqual(json.loads(response.content)["site"]["name"],"ISPRA")
        self.assertEqual(json.loads(response.content)["status"]["value"],"offline")
    
    def test_put_config_context(self) -> None:
        """ Will test the update of config context into the device """

        # First we need the config context ID

        config_context = requests.get(url=f"http://{HOST}:{PORT}/api/extras/config-contexts/", headers=HEADERS)
        config_context_id = json.loads(config_context.content)["results"][0]["id"]

        config_context_data = requests.get(url=f"http://{HOST}:{PORT}/api/extras/config-contexts/{config_context_id}/", headers=HEADERS)
        data = json.loads(config_context_data.content)["data"]
        print(data)

        device_type = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/device-types/", headers=HEADERS)
        device_type_id = json.loads(device_type.content)["results"][0]["id"]

        device_role = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/device-roles/", headers=HEADERS)
        device_role_id = json.loads(device_role.content)["results"][0]["id"]

        site =  requests.get(url=f"http://{HOST}:{PORT}/api/dcim/sites/", headers=HEADERS)
        site_id = json.loads(site.content)["results"][0]["id"]

        device = requests.get(url=f"http://{HOST}:{PORT}/api/dcim/devices/", headers=HEADERS)
        device_id = json.loads(device.content)["results"][0]["id"]

        upload_config_context = requests.put(
            url=f"http://{HOST}:{PORT}/api/dcim/devices/{device_id}/",
            headers=HEADERS,
            json={
                "device_type": device_type_id,
                "role": device_role_id,
                "site": site_id,
                "local_context_data": data
            },
            timeout=5
        )

        self.assertEqual(upload_config_context.status_code,200)

        self.assertEqual(json.loads(upload_config_context.content)["local_context_data"]["radius_servers"][0],"1.1.1.1")
        self.assertEqual(json.loads(upload_config_context.content)["local_context_data"]["radius_servers"][1],"2.2.2.2")

        
        
if __name__ == "__main__":
    unittest.main()