"""SchemaValidator - Validate YAML against Pydantic models.

Contract: CNT-T2-SVC-008
Traceability: UC-004
"""

from pathlib import Path
from typing import Any

from laida_cli.adapters.schema_adapter import SchemaAdapter
from laida_cli.adapters.yaml_adapter import YamlAdapter
from laida_cli.domain.validation_result import ValidationResult
from laida_cli.ports.yaml_port import YamlPort


class SchemaValidator:
    """Application service for validating YAML files against schemas."""

    def __init__(
        self,
        yaml_port: YamlPort | None = None,
        schema_adapter: SchemaAdapter | None = None,
    ) -> None:
        """Initialize schema validator.

        Args:
            yaml_port: Port for YAML operations (uses default adapter if None)
            schema_adapter: Schema adapter for Pydantic validation
        """
        self._yaml: YamlPort = yaml_port or YamlAdapter()
        self._schema = schema_adapter or SchemaAdapter()

    def validate_yaml(
        self, content: str, schema_name: str
    ) -> ValidationResult:
        """Validate YAML content against a named schema.

        Args:
            content: YAML content string
            schema_name: Name of the schema to validate against

        Returns:
            ValidationResult with outcome
        """
        try:
            data = self._yaml.parse(content)
        except ValueError as e:
            return ValidationResult.failure([f"YAML parse error: {e}"])

        return self._validate_data(data, schema_name)

    def validate_file(self, path: Path, schema_name: str) -> ValidationResult:
        """Validate a YAML file against a named schema.

        Args:
            path: Path to YAML file
            schema_name: Name of the schema to validate against

        Returns:
            ValidationResult with outcome
        """
        if not path.exists():
            return ValidationResult.failure([f"File not found: {path}"])

        try:
            data = self._yaml.parse_file(path)
        except ValueError as e:
            return ValidationResult.failure([f"YAML parse error: {e}"])

        return self._validate_data(data, schema_name)

    def _validate_data(
        self, data: dict[str, Any], schema_name: str
    ) -> ValidationResult:
        """Validate parsed data against schema.

        Args:
            data: Parsed YAML data
            schema_name: Schema name

        Returns:
            ValidationResult with outcome
        """
        # For now, do basic structural validation
        # In a full implementation, we'd load Pydantic models from templates
        errors: list[str] = []
        warnings: list[str] = []

        # Check for required top-level key
        expected_key = schema_name.replace("_", "")
        if not data:
            errors.append("Empty YAML document")
        elif schema_name not in data and expected_key not in data:
            # Allow variations of the key
            warnings.append(
                f"Expected top-level key '{schema_name}' or '{expected_key}'"
            )

        if errors:
            return ValidationResult.failure(errors)
        if warnings:
            return ValidationResult.with_warnings(warnings)
        return ValidationResult.success()

    def list_schemas(self) -> list[str]:
        """List available schemas.

        Returns:
            List of schema names
        """
        return self._schema.list_schemas()
