from ichec_django_core.models import Member
from ichec_django_core.test import (
    AuthAPITestCase,
    add_group_permissions,
    setup_default_users_and_groups,
)

from marinerg_facility.models import Facility
from marinerg_facility.test import setup_default_facilities

from marinerg_test_access.models import (
    AccessApplication,
    FacilityTestReport,
)
from marinerg_test_access.client.resources import (
    create_test_report,
)
from marinerg_test_access.test import (
    setup_default_access_calls,
    setup_application,
    setup_review,
    setup_decision,
    setup_test_report,
)


class TestTestReportView(AuthAPITestCase):

    def setUp(self):
        self.url = "/api/facility_test_reports/"
        setup_default_users_and_groups()

        add_group_permissions(
            "members",
            FacilityTestReport,
            [
                "add_facilitytestreport",
            ],
        )

        add_group_permissions(
            "admins",
            FacilityTestReport,
            [
                "view_facilitytestreport",
            ],
        )

        add_group_permissions(
            "admins",
            AccessApplication,
            [
                "view_accessapplication",
            ],
        )

        add_group_permissions(
            "admins",
            Facility,
            [
                "view_facility",
            ],
        )

        self.internal, self.public, _ = setup_default_access_calls()
        self.application1 = setup_application(self.public, "applicant")
        self.application2 = setup_application(self.public, "applicant2")
        self.application3 = setup_application(self.public, "applicant3")

        self.review1 = setup_review(self.application1, "reviewer1")
        self.review2 = setup_review(self.application1, "reviewer2")
        setup_review(self.application3, "reviewer1")
        setup_review(self.application3, "reviewer2")

        facility_member = Member.objects.get(username="other_member")
        self.facility, _, _ = setup_default_facilities(facility_member)

        self.decision1 = setup_decision(self.application1, self.facility, "chair")
        self.decision2 = setup_decision(self.application2, self.facility, "chair")
        self.decision3 = setup_decision(self.application3, self.facility, "chair")

        self.report1 = setup_test_report(
            self.application1, self.facility, facility_member
        )
        self.report2 = setup_test_report(
            self.application2, self.facility, facility_member
        )

        application = self.auth_raw_get(
            "admin_user", f"/api/access_applications/{self.application3.id}/"
        )
        facility = self.auth_raw_get(
            "admin_user", f"/api/facilities/{self.facility.id}/"
        )
        self.template = create_test_report(
            application.body["url"], facility.body["url"]
        )

    def test_list_access(self):

        scenarios = (
            ["", 0, 401, "Public can't see reports"],
            ["regular_user", 0, 200, "Registered can't see reports"],
            ["member", 0, 200, "Member can't see reports"],
            ["coordinator", 2, 200, "Coordinator can see their call's reports"],
            ["reviewer1", 0, 200, "Reviewer can't see any reports"],
            ["chair", 0, 200, "Chair can't see their call's reports"],
            ["applicant", 0, 200, "Applicant can't see reports"],
            ["admin_user", 2, 200, "Admin can see reports"],
        )
        for user, count, status, msg in scenarios:
            if user:
                response = self.assert_status(self.auth_list(user), status, msg)
            else:
                response = self.assert_status(self.public_list(), status, msg)

            if status < 400:
                self.assertEqual(response.body.count, count, msg)

    def test_detail_access(self):

        report = self.report1.id
        scenarios = (
            ["", report, 401, "Public can't view report"],
            ["regular_user", report, 404, "Registered can't view report"],
            ["member", report, 404, "Member can't view report"],
            ["applicant", report, 404, "Applicant can't view report"],
            ["coordinator", report, 200, "Coordinator can view report"],
            ["chair", report, 404, "Chair can' view report"],
            ["reviewer1", report, 404, "Reviewer can't view report"],
            ["admin_user", report, 200, "Admin can view report"],
        )

        for user, item, status, msg in scenarios:
            if user:
                self.assert_status(self.auth_detail(user, item), status, msg)
            else:
                self.assert_status(self.detail(item), status, msg)

    def test_create_permissions(self):

        scenarios = (
            ["", 401, "Public can't create, no auth"],
            ["regular_user", 403, "Regular user can't create, not facility"],
            ["other_member", 201, "Facility member can create"],
            ["member", 400, "Member can't create, not facility"],
            ["applicant", 403, "Applicant can't create, not facility"],
            ["coordinator", 403, "Coordinator can't create, not facility"],
            ["chair", 403, "Chair can't create"],
            ["reviewer1", 403, "Reviewer can't create"],
            ["admin_user", 400, "Admin can't create, not facility"],
        )

        for user, status, msg in scenarios:
            if user:
                self.assert_status(self.auth_create(user, self.template), status, msg)
            else:
                self.assert_status(self.create(self.template), status, msg)
