import os
import unittest

os.environ.setdefault("DATABASE_URL", "mysql+pymysql://test:test@127.0.0.1/documenta")
os.environ.setdefault("REDIS_URL", "redis://127.0.0.1:6379/0")
os.environ.setdefault("APP_ENCRYPTION_KEY", "dGVzdC1rZXktZm9yLWRvY3VtZW50YS0zMmJ5dGVzISE=")
os.environ.setdefault("PII_HMAC_KEY", "test-pii-key")
os.environ.setdefault("ACCESS_TOKEN_HMAC_KEY", "test-access-key")

from fastapi.testclient import TestClient

from app.main import app
from app.services.observability import portal_name, safe_route
from app.tasks.celery_app import celery_app


class H12ReleaseContractTests(unittest.TestCase):
    def setUp(self):
        self.client = TestClient(app, raise_server_exceptions=False)

    def test_h12_routes_and_version_are_registered(self):
        paths = {route.path for route in app.routes}
        expected = {
            "/api/v1/health/ready",
            "/api/v1/panel/admin/operations",
            "/api/v1/panel/admin/operations/run",
            "/api/v1/panel/admin/operations/runs/{run_uuid}",
        }
        self.assertEqual(app.version, "1.20.0")
        self.assertTrue(expected.issubset(paths), expected - paths)

    def test_privileged_surfaces_reject_anonymous_requests(self):
        for path in (
            "/api/v1/panel/admin/operations",
            "/api/v1/panel/admin/verificacion",
            "/api/v1/panel/admin/editorial",
            "/api/v1/panel/admin/territory",
            "/api/v1/panel/admin/security",
        ):
            with self.subTest(path=path):
                response = self.client.get(path, headers={"Host": "documenta.cl"})
                self.assertEqual(response.status_code, 401)

    def test_mutating_operations_reject_anonymous_requests(self):
        response = self.client.post(
            "/api/v1/panel/admin/operations/run",
            headers={"Host": "documenta.cl", "X-CSRF-Token": "not-a-real-token"},
        )
        self.assertEqual(response.status_code, 401)

    def test_api_security_headers_and_request_id_sanitization(self):
        response = self.client.get(
            "/api/v1/does-not-exist",
            headers={"Host": "documenta.cl", "X-Request-ID": "<secret-injection>"},
        )
        self.assertEqual(response.status_code, 404)
        self.assertNotEqual(response.headers["x-request-id"], "<secret-injection>")
        self.assertEqual(response.headers["x-frame-options"], "DENY")
        self.assertIn("default-src 'none'", response.headers["content-security-policy"])
        self.assertIn("max-age=31536000", response.headers["strict-transport-security"])

    def test_metrics_labels_are_bounded(self):
        self.assertEqual(portal_name("notaria.documenta.cl"), "notaria")
        self.assertEqual(portal_name("attacker.example"), "interno")
        request = type("Request", (), {
            "scope": {},
            "url": type("URL", (), {"path": "/api/v1/documents/12345678901234567890"})(),
        })()
        self.assertEqual(safe_route(request), "/api/v1/documents/:id")

    def test_worker_scheduler_heartbeat_is_scheduled(self):
        schedule = celery_app.conf.beat_schedule
        self.assertEqual(schedule["heartbeat-operacion-h12"]["task"], "app.tasks.jobs.heartbeat_operacion")
        self.assertLessEqual(float(schedule["heartbeat-operacion-h12"]["schedule"]), 60)


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