from __future__ import annotations

import unittest

from aegis.validation import load_schema, validate_context_data


class ValidationTests(unittest.TestCase):
    def setUp(self) -> None:
        self.schema = load_schema()

    def test_valid_context_passes(self) -> None:
        context = {
            "version": "0.2",
            "services": [
                {
                    "id": "user-api",
                    "name": "User API",
                    "description": "Public user API",
                }
            ],
            "trust_boundaries": [
                {
                    "id": "public-to-internal",
                    "name": "Public to internal",
                    "crossing_requirements": [
                        {
                            "id": "enforce-authn",
                            "text": "Must authenticate",
                            "severity": "critical",
                        }
                    ],
                }
            ],
            "data_classifications": [
                {
                    "id": "user-pii",
                    "name": "PII",
                    "handling_rules": [
                        {
                            "id": "no-pii-logs",
                            "text": "No raw pii logs",
                            "severity": "critical",
                        }
                    ],
                }
            ],
            "approved_patterns": [
                {
                    "id": "auth-middleware",
                    "name": "Auth middleware",
                    "description": "Use standard auth middleware",
                    "requirements": [],
                }
            ],
            "anti_patterns": [
                {
                    "id": "raw-sql",
                    "name": "Raw SQL",
                    "description": "Do not interpolate SQL",
                    "severity": "critical",
                    "requirements": [],
                }
            ],
            "authorization_policies": [
                {
                    "id": "admin-only",
                    "name": "Admin only",
                    "description": "Admin access policy",
                    "required_controls": [
                        {
                            "id": "enforce-admin-role-check",
                            "text": "Must enforce admin role checks",
                            "severity": "critical",
                        }
                    ],
                }
            ],
            "input_validations": [
                {
                    "id": "request-body",
                    "name": "Request body validation",
                    "description": "Validate request body",
                    "validation_rules": [
                        {
                            "id": "validate-request-schema",
                            "text": "Request body must match schema",
                            "severity": "high",
                        }
                    ],
                }
            ],
            "security_configs": [
                {
                    "id": "security-headers",
                    "name": "Security headers",
                    "description": "Set hardened headers",
                    "scope": "edge",
                    "when": {
                        "boundary_crossings": ["public-to-internal"],
                        "auth_scopes": ["admin-only"],
                        "input_sources": ["request-body"],
                        "actions": ["create-endpoint"],
                    },
                    "rules": [
                        {
                            "id": "set-security-headers",
                            "text": "Set baseline security headers",
                            "severity": "medium",
                        }
                    ],
                }
            ],
            "secrets_management": [
                {
                    "id": "no-hardcoded-secrets",
                    "name": "No hardcoded secrets",
                    "description": "No inline secrets",
                    "when": {},
                    "rules": [
                        {
                            "id": "store-secrets-in-manager",
                            "text": "Store secrets in managed secret store",
                            "severity": "critical",
                        }
                    ],
                }
            ],
            "pipeline_policies": [
                {
                    "id": "dependency-scanning",
                    "name": "Dependency scanning",
                    "description": "Run scans in CI",
                    "when": {},
                    "rules": [
                        {
                            "id": "run-dependency-vulnerability-scan",
                            "text": "Run dependency vulnerability scan in CI",
                            "severity": "high",
                        }
                    ],
                }
            ],
            "error_handling": [
                {
                    "id": "safe-error-responses",
                    "name": "Safe error responses",
                    "description": "No sensitive data in errors",
                    "when": {"actions": ["create-endpoint"]},
                    "rules": [
                        {
                            "id": "no-sensitive-error-details",
                            "text": "Error responses must not expose sensitive internals",
                            "severity": "high",
                        }
                    ],
                }
            ],
        }

        report = validate_context_data(context=context, schema=self.schema)
        self.assertTrue(report.valid)
        self.assertEqual(report.errors, [])

    def test_duplicate_ids_in_new_section_fail(self) -> None:
        context = {
            "version": "0.2",
            "trust_boundaries": [
                {
                    "id": "public-to-internal",
                    "name": "Public to internal",
                    "crossing_requirements": [
                        {
                            "id": "req-a",
                            "text": "A",
                            "severity": "low",
                        }
                    ],
                },
            ],
            "data_classifications": [],
            "approved_patterns": [],
            "anti_patterns": [],
            "authorization_policies": [
                {
                    "id": "admin-only",
                    "name": "Admin only",
                    "description": "Policy A",
                    "required_controls": [],
                },
                {
                    "id": "admin-only",
                    "name": "Admin only duplicate",
                    "description": "Policy B",
                    "required_controls": [],
                },
            ],
        }

        report = validate_context_data(context=context, schema=self.schema)
        self.assertFalse(report.valid)
        self.assertTrue(any("Duplicate id" in err["message"] for err in report.errors))


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