from django.test import TestCase
from django.urls import reverse
from rest_framework.test import APIClient

from astrobin.tests.generators import Generators
from astrobin_apps_equipment.models.equipment_item import EquipmentItemReviewerDecision
from astrobin_apps_equipment.tests.equipment_generators import EquipmentGenerators
from common.constants import GroupName


class TestApiSensorViewSet(TestCase):
    def test_list_with_no_items(self):
        client = APIClient()

        response = client.get(reverse('astrobin_apps_equipment:sensor-list'), format='json')
        self.assertEquals(0, response.data['count'])

    def test_list_with_items(self):
        client = APIClient()

        sensor = EquipmentGenerators.sensor(reviewer_decision=EquipmentItemReviewerDecision.APPROVED)

        response = client.get(reverse('astrobin_apps_equipment:sensor-list'), format='json')
        self.assertEquals(1, response.data['count'])
        self.assertEquals(sensor.name, response.data['results'][0]['name'])

    def test_detail_contains_related_cameras(self):
        client = APIClient()

        sensor1 = EquipmentGenerators.sensor(reviewer_decision=EquipmentItemReviewerDecision.APPROVED)
        sensor2 = EquipmentGenerators.sensor(reviewer_decision=EquipmentItemReviewerDecision.APPROVED)
        camera1a = EquipmentGenerators.camera(reviewer_decision=EquipmentItemReviewerDecision.APPROVED, sensor=sensor1)
        camera1b = EquipmentGenerators.camera(reviewer_decision=EquipmentItemReviewerDecision.APPROVED, sensor=sensor1)
        camera2 = EquipmentGenerators.camera(reviewer_decision=EquipmentItemReviewerDecision.APPROVED, sensor=sensor2)

        camera1b.user_count = 1
        camera1b.save()

        response = client.get(reverse('astrobin_apps_equipment:sensor-detail', args=(sensor1.pk,)), format='json')
        self.assertEquals([camera1b.id, camera1a.id], list(response.data['cameras']))
        response = client.get(reverse('astrobin_apps_equipment:sensor-detail', args=(sensor2.pk,)), format='json')
        self.assertEquals([camera2.id], list(response.data['cameras']))

    def test_deleting_not_allowed(self):
        client = APIClient()

        sensor = EquipmentGenerators.sensor()

        response = client.delete(reverse('astrobin_apps_equipment:sensor-detail', args=(sensor.pk,)), format='json')
        self.assertEquals(405, response.status_code)

        user = Generators.user(groups=[GroupName.EQUIPMENT_MODERATORS])
        client.login(username=user.username, password=user.password)
        client.force_authenticate(user=user)

        response = client.delete(reverse('astrobin_apps_equipment:sensor-detail', args=(sensor.pk,)), format='json')
        self.assertEquals(405, response.status_code)

    def test_post_not_allowed(self):
        client = APIClient()

        response = client.post(reverse('astrobin_apps_equipment:sensor-list'), {
            'brand': EquipmentGenerators.brand().pk,
            'name': 'Sensor Foo',
        }, format='json')
        self.assertEquals(403, response.status_code)

        user = Generators.user()
        client.login(username=user.username, password=user.password)
        client.force_authenticate(user=user)

        response = client.post(reverse('astrobin_apps_equipment:sensor-list'), {
            'brand': EquipmentGenerators.brand().pk,
            'name': 'Sensor Foo',
        }, format='json')
        self.assertEquals(403, response.status_code)

    def test_created_by(self):
        client = APIClient()

        user = Generators.user(groups=[GroupName.EQUIPMENT_MODERATORS])
        client.login(username=user.username, password=user.password)
        client.force_authenticate(user=user)

        response = client.post(reverse('astrobin_apps_equipment:sensor-list'), {
            'brand': EquipmentGenerators.brand().pk,
            'name': 'Sensor Foo',
        }, format='json')
        self.assertEquals(201, response.status_code)
        self.assertEquals(user.pk, response.data['created_by'])

    def test_list_returns_only_own_DIYs(self):
        user = Generators.user()
        first = EquipmentGenerators.sensor(created_by=user)
        first.brand = None
        first.save()

        second = EquipmentGenerators.sensor()
        second.brand = None
        second.save()

        client = APIClient()
        client.force_authenticate(user=user)

        response = client.get(reverse('astrobin_apps_equipment:sensor-list'), format='json')
        self.assertEquals(1, response.data['count'])
        self.assertEquals(first.name, response.data['results'][0]['name'])

    def test_find_recently_used_not_supported(self):
        user = Generators.user()

        client = APIClient()
        client.force_authenticate(user=user)

        response = client.get(
            reverse('astrobin_apps_equipment:sensor-list') + 'recently-used/', format='json'
        )

        self.assertEquals(400, response.status_code)


