"""Regression guards for removal of the isolated clinical scheduling path."""

import importlib.util
import os
from pathlib import Path
import subprocess
import sys

from django.apps import apps
from django.core.management import get_commands
from django.db import models
from django.test import SimpleTestCase, override_settings
from django.urls import Resolver404, resolve

from api.admin_permission_conf import ROUTE_PERMISSION_REQUIREMENTS
from api.views.admin.preschedule_request import PrescheduleRequest
from api.views.admin.schedule_request import ScheduleRequest


ROOT = Path(__file__).resolve().parents[2]
HISTORICAL_MODELS = {
    "clinicalrotationdelivery",
    "clinicalrotationplanitem",
    "clinicalrotationsyncreceipt",
    "clinicalrotationleasehandoff",
    "clinicalrotationresponsereceipt",
    "clinicalrotationquarantine",
    "clinicalrotationplan",
}


class ClinicalRotationRetirementTests(SimpleTestCase):
    def test_clinical_endpoints_are_not_registered(self):
        for suffix in ("preview-request", "schedule-request", "status"):
            with self.subTest(endpoint=suffix), self.assertRaises(Resolver404):
                resolve(f"/api/admin/clinical-rotation/{suffix}")

    @override_settings(CLINICAL_ROTATION_SCHEDULING_ENABLED=True)
    def test_stale_feature_flag_cannot_restore_clinical_routes(self):
        for suffix in ("preview-request", "schedule-request", "status"):
            with self.subTest(endpoint=suffix), self.assertRaises(Resolver404):
                resolve(f"/api/admin/clinical-rotation/{suffix}")

    def test_generic_schedule_and_preschedule_keep_their_views(self):
        for route, view in (
            ("schedule-request", ScheduleRequest),
            ("preschedule-request", PrescheduleRequest),
        ):
            with self.subTest(route=route):
                self.assertIs(resolve(f"/api/admin/{route}").func.view_class, view)

    def test_clinical_permission_aliases_are_removed(self):
        self.assertFalse(
            any(name.startswith("clinical_rotation;") for name in ROUTE_PERMISSION_REQUIREMENTS)
        )

    def test_clinical_management_commands_are_not_discoverable(self):
        self.assertFalse(any("clinical_rotation" in name for name in get_commands()))

    def test_clinical_runtime_modules_are_not_importable(self):
        for name in (
            "api.services.scheduling.clinical_rotation_plan",
            "api.services.scheduling.clinical_rotation_apply",
            "api.services.scheduling.clinical_rotation_response",
            "api.services.scheduling.clinical_rotation_reconcile",
            "api.services.scheduling.clinical_rotation_runtime",
            "kafka_consumer.clinical_rotation_consumer_runtime",
            "kafka_consumer.clinical_rotation_delivery_publisher",
            "kafka_consumer.clinical_rotation_sync_worker",
        ):
            with self.subTest(module=name):
                self.assertIsNone(importlib.util.find_spec(name))

    def test_old_environment_variables_do_not_create_runtime_configuration(self):
        env = {
            **os.environ,
            "DJANGO_SETTINGS_MODULE": "backend.test_settings",
            "CLINICAL_ROTATION_SCHEDULING_ENABLED": "True",
            "CLINICAL_ROTATION_RECOVERY_ENABLED": "True",
            "CLINICAL_ROTATION_FENCE_FLEET_READY": "True",
        }
        result = subprocess.run(
            [sys.executable, "-c", "from django.conf import settings; "
             "assert not hasattr(settings, 'CLINICAL_ROTATION_CONFIG'); "
             "assert not hasattr(settings, 'CLINICAL_ROTATION_SCHEDULING_ENABLED')"],
            cwd=ROOT, env=env, check=False, capture_output=True, text=True, timeout=30,
        )
        self.assertEqual(result.returncode, 0, result.stderr)

    def test_deployment_cannot_reactivate_clinical_workers(self):
        workflow = (ROOT / ".github/workflows/deploy.yml").read_text()
        self.assertNotIn("clinical_rotation_action", workflow)
        self.assertNotIn("clinical-rotation.yml", workflow)
        self.assertFalse((ROOT / ".github/workflows/clinical-rotation.yml").exists())
        self.assertFalse(list((ROOT / "deploy").glob("*clinical_rotation*")))

    def test_historical_metadata_remains_registered_for_existing_data(self):
        registered = {model._meta.model_name for model in apps.get_app_config("api").get_models()}
        self.assertTrue(HISTORICAL_MODELS.issubset(registered))

    def test_historical_records_keep_existing_generic_delete_protection(self):
        # Forgetting these ORM relations while retaining SQL foreign keys would
        # replace Django ProtectedError with raw integrity errors on generic
        # deletes. Runtime retirement must not change that existing behavior.
        for model_name, fields in (
            ("ClinicalRotationPlan", ("created_by", "academic_term", "module")),
            ("ClinicalRotationPlanItem", ("activity", "student_set", "activity_template")),
        ):
            model = apps.get_model("api", model_name)
            for field_name in fields:
                with self.subTest(model=model_name, field=field_name):
                    field = model._meta.get_field(field_name)
                    self.assertIs(field.remote_field.on_delete, models.PROTECT)
                    reverse = field.remote_field
                    self.assertIn(reverse, reverse.model._meta.related_objects)
