"""
Schema validation quality gate.

Implements FR-9.1: Validate generated artifacts against JSON schemas.
Uses the jsonschema library for validation.
"""

import json
import uuid
from typing import Any, Dict, Optional

import jsonschema

from markitect.prompts.quality.models import (
    GateType,
    QualityGate,
    ValidationDiagnostic,
    ValidationResult,
    ValidationStatus,
)


class SchemaValidationGate(QualityGate):
    """
    Validates artifact content against a JSON schema.

    Parses content as JSON and validates against the provided schema
    using the jsonschema library.
    """

    def __init__(
        self,
        schema: Dict[str, Any],
        gate_id: Optional[str] = None,
        name: str = "schema",
    ):
        """
        Initialize with a JSON schema.

        Args:
            schema: JSON Schema dictionary
            gate_id: Optional gate identifier (auto-generated if not provided)
            name: Human-readable gate name
        """
        super().__init__(
            gate_id=gate_id or str(uuid.uuid4()),
            name=name,
            gate_type=GateType.SCHEMA,
        )
        self.schema = schema

    def validate(self, content: str, artifact_id: str) -> ValidationResult:
        """
        Validate content against the JSON schema.

        Parses the content as JSON, then validates against the schema.
        Returns FAIL if content is not valid JSON or fails schema validation.

        Args:
            content: JSON content string to validate
            artifact_id: ID of the artifact being validated

        Returns:
            ValidationResult with status and diagnostics
        """
        diagnostics = []

        # Parse JSON
        try:
            data = json.loads(content)
        except (json.JSONDecodeError, TypeError) as e:
            diagnostics.append(
                ValidationDiagnostic(
                    code="INVALID_JSON",
                    message=f"Content is not valid JSON: {e}",
                    severity="error",
                )
            )
            return ValidationResult.create(
                gate_id=self.id,
                gate_type=self.gate_type,
                artifact_id=artifact_id,
                status=ValidationStatus.FAIL,
                score=0.0,
                diagnostics=diagnostics,
            )

        # Validate against schema
        validator = jsonschema.Draft7Validator(self.schema)
        errors = list(validator.iter_errors(data))

        if not errors:
            return ValidationResult.create(
                gate_id=self.id,
                gate_type=self.gate_type,
                artifact_id=artifact_id,
                status=ValidationStatus.PASS,
                score=1.0,
                diagnostics=[],
            )

        for error in errors:
            path = ".".join(str(p) for p in error.absolute_path) or "(root)"
            diagnostics.append(
                ValidationDiagnostic(
                    code="SCHEMA_VIOLATION",
                    message=f"At '{path}': {error.message}",
                    severity="error",
                )
            )

        # Score based on proportion of passing validations
        total_checks = len(errors) + 1  # approximate
        score = max(0.0, 1.0 - len(errors) / total_checks)

        return ValidationResult.create(
            gate_id=self.id,
            gate_type=self.gate_type,
            artifact_id=artifact_id,
            status=ValidationStatus.FAIL,
            score=score,
            diagnostics=diagnostics,
        )
