import json
from rest_framework import status
from rest_framework.test import APITestCase


class SiteTest(APITestCase):

    fixtures = [
        'dcim',
        'ipam',
        'extras',
    ]

    standard_fields = [
        'id',
        'name',
        'slug',
        'tenant',
        'facility',
        'asn',
        'physical_address',
        'shipping_address',
        'comments',
        'count_prefixes',
        'count_vlans',
        'count_racks',
        'count_devices',
        'count_circuits'
    ]

    nested_fields = [
        'id',
        'name',
        'slug'
    ]

    rack_fields = [
        'id',
        'name',
        'facility_id',
        'display_name',
        'site',
        'group',
        'tenant',
        'role',
        'type',
        'width',
        'u_height',
        'comments'
    ]

    graph_fields = [
        'name',
        'embed_url',
        'embed_link',
    ]

    def test_get_list(self, endpoint='/api/dcim/sites/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in content:
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.standard_fields),
            )

    def test_get_detail(self, endpoint='/api/dcim/sites/1/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            sorted(content.keys()),
            sorted(self.standard_fields),
        )

    def test_get_site_list_rack(self, endpoint='/api/dcim/sites/1/racks/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in json.loads(response.content):
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.rack_fields),
            )
            # Check Nested Serializer.
            self.assertEqual(
                sorted(i.get('site').keys()),
                sorted(self.nested_fields),
            )

    def test_get_site_list_graphs(self, endpoint='/api/dcim/sites/1/graphs/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in json.loads(response.content):
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.graph_fields),
            )


class RackTest(APITestCase):
    fixtures = [
        'dcim',
        'ipam'
    ]

    nested_fields = [
        'id',
        'name',
        'facility_id',
        'display_name'
    ]

    standard_fields = [
        'id',
        'name',
        'facility_id',
        'display_name',
        'site',
        'group',
        'tenant',
        'role',
        'type',
        'width',
        'u_height',
        'comments'
    ]

    detail_fields = [
        'id',
        'name',
        'facility_id',
        'display_name',
        'site',
        'group',
        'tenant',
        'role',
        'type',
        'width',
        'u_height',
        'comments',
        'front_units',
        'rear_units'
    ]

    def test_get_list(self, endpoint='/api/dcim/racks/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in content:
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.standard_fields),
            )
            self.assertEqual(
                sorted(i.get('site').keys()),
                sorted(SiteTest.nested_fields),
            )

    def test_get_detail(self, endpoint='/api/dcim/racks/1/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            sorted(content.keys()),
            sorted(self.detail_fields),
        )
        self.assertEqual(
            sorted(content.get('site').keys()),
            sorted(SiteTest.nested_fields),
        )


class ManufacturersTest(APITestCase):

    fixtures = [
        'dcim',
        'ipam'
    ]

    standard_fields = [
        'id',
        'name',
        'slug',
    ]

    nested_fields = standard_fields

    def test_get_list(self, endpoint='/api/dcim/manufacturers/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in content:
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.standard_fields),
            )

    def test_get_detail(self, endpoint='/api/dcim/manufacturers/1/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            sorted(content.keys()),
            sorted(self.standard_fields),
        )


class DeviceTypeTest(APITestCase):

    fixtures = ['dcim', 'ipam']

    standard_fields = [
        'id',
        'manufacturer',
        'model',
        'slug',
        'part_number',
        'u_height',
        'is_full_depth',
        'is_console_server',
        'is_pdu',
        'is_network_device',
    ]

    nested_fields = [
        'id',
        'manufacturer',
        'model',
        'slug'
    ]

    def test_get_list(self, endpoint='/api/dcim/device-types/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in content:
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.standard_fields),
            )

    def test_detail_list(self, endpoint='/api/dcim/device-types/1/'):
        # TODO: details returns list view.
        # response = self.client.get(endpoint)
        # content = json.loads(response.content)
        # self.assertEqual(response.status_code, status.HTTP_200_OK)
        # self.assertEqual(
        #     sorted(content.keys()),
        #     sorted(self.standard_fields),
        # )
        # self.assertEqual(
        #     sorted(content.get('manufacturer').keys()),
        #     sorted(ManufacturersTest.nested_fields),
        # )
        pass


class DeviceRolesTest(APITestCase):

    fixtures = ['dcim', 'ipam']

    standard_fields = ['id', 'name', 'slug', 'color']

    nested_fields = ['id', 'name', 'slug']

    def test_get_list(self, endpoint='/api/dcim/device-roles/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in content:
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.standard_fields),
            )

    def test_get_detail(self, endpoint='/api/dcim/device-roles/1/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            sorted(content.keys()),
            sorted(self.standard_fields),
        )


class PlatformsTest(APITestCase):

    fixtures = ['dcim', 'ipam']

    standard_fields = ['id', 'name', 'slug', 'rpc_client']

    nested_fields = ['id', 'name', 'slug']

    def test_get_list(self, endpoint='/api/dcim/platforms/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for i in content:
            self.assertEqual(
                sorted(i.keys()),
                sorted(self.standard_fields),
            )

    def test_get_detail(self, endpoint='/api/dcim/platforms/1/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            sorted(content.keys()),
            sorted(self.standard_fields),
        )


class DeviceTest(APITestCase):

    fixtures = ['dcim', 'ipam']

    standard_fields = [
        'id',
        'name',
        'display_name',
        'device_type',
        'device_role',
        'tenant',
        'platform',
        'serial',
        'asset_tag',
        'rack',
        'position',
        'face',
        'parent_device',
        'status',
        'primary_ip',
        'primary_ip4',
        'primary_ip6',
        'comments',
    ]

    nested_fields = ['id', 'name', 'display_name']

    def test_get_list(self, endpoint='/api/dcim/devices/'):
        response = self.client.get(endpoint)
        content = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        for device in content:
            self.assertEqual(
                sorted(device.keys()),
                sorted(self.standard_fields),
            )
            self.assertEqual(
                sorted(device.get('device_type')),
                sorted(DeviceTypeTest.nested_fields),
            )
            self.assertEqual(
                sorted(device.get('device_role')),