"""
Module: validator
Description: Pack validation logic

Implements:
    - docs/cli/reference.md#huitzo-validate
"""

from pathlib import Path
from typing import Optional

import yaml
from pydantic import BaseModel, Field


class ValidationResult(BaseModel):
    """Result of pack validation."""

    valid: bool
    errors: list[str] = Field(default_factory=list)
    warnings: list[str] = Field(default_factory=list)


class PackValidator:
    """Validates Intelligence Pack structure and configuration."""

    def __init__(self, pack_root: Optional[Path] = None) -> None:
        """Initialize validator.

        Args:
            pack_root: Root directory of pack. If None, uses current directory.
        """
        self.pack_root = pack_root or Path.cwd()

    def validate(self, strict: bool = False) -> ValidationResult:
        """Validate pack structure.

        Args:
            strict: If True, treat warnings as errors

        Returns:
            ValidationResult with status and messages
        """
        errors = []
        warnings = []

        # Check pyproject.toml
        pyproject_path = self.pack_root / "pyproject.toml"
        if not pyproject_path.exists():
            errors.append("pyproject.toml not found")
        else:
            tomllib = None
            try:
                import tomllib  # type: ignore[assignment]  # Python 3.11+
            except ImportError:
                try:
                    import tomli as tomllib  # type: ignore[no-redef]
                except ImportError:
                    warnings.append("Could not validate pyproject.toml (tomli not installed)")

            if tomllib is not None:
                try:
                    with open(pyproject_path, "rb") as f:
                        pyproject = tomllib.load(f)
                    if "project" not in pyproject:
                        errors.append("pyproject.toml missing [project] section")
                    if "project" in pyproject and "entry-points" not in pyproject.get(
                        "project", {}
                    ):
                        warnings.append("pyproject.toml missing huitzo.packs entry point")
                except Exception as e:
                    errors.append(f"Invalid pyproject.toml: {e}")

        # Check huitzo.yaml
        huitzo_yaml_path = self.pack_root / "huitzo.yaml"
        if not huitzo_yaml_path.exists():
            errors.append("huitzo.yaml not found")
        else:
            try:
                with open(huitzo_yaml_path) as f:
                    huitzo_config = yaml.safe_load(f)

                if not huitzo_config:
                    errors.append("huitzo.yaml is empty")
                else:
                    pack = huitzo_config.get("pack")
                    if not isinstance(pack, dict):
                        errors.append("huitzo.yaml missing required 'pack:' section")
                    else:
                        required_fields = ["name", "namespace", "version", "description"]
                        for field in required_fields:
                            if not pack.get(field):
                                errors.append(f"huitzo.yaml pack.{field} is required")
                        if pack.get("visibility") not in ("public", "private", None):
                            errors.append(
                                "huitzo.yaml pack.visibility must be 'public' or 'private'"
                            )

            except yaml.YAMLError as e:
                errors.append(f"Invalid YAML in huitzo.yaml: {e}")
            except Exception as e:
                errors.append(f"Error reading huitzo.yaml: {e}")

        # Check source directory
        src_dir = self.pack_root / "src"
        if not src_dir.exists():
            warnings.append("src/ directory not found")
        else:
            # Look for Python packages
            found_package = False
            for item in src_dir.iterdir():
                if item.is_dir() and not item.name.startswith("_"):
                    if (item / "__init__.py").exists():
                        found_package = True
                        break

            if not found_package:
                warnings.append("No Python package found in src/")

        # Check tests
        tests_dir = self.pack_root / "tests"
        if not tests_dir.exists():
            warnings.append("tests/ directory not found")
        elif not list(tests_dir.glob("test_*.py")):
            warnings.append("No tests found in tests/ directory")

        # Check README
        readme_path = self.pack_root / "README.md"
        if not readme_path.exists():
            warnings.append("README.md not found")

        # Determine validity
        valid = len(errors) == 0
        if strict and len(warnings) > 0:
            errors.extend(warnings)
            warnings = []
            valid = False

        return ValidationResult(valid=valid, errors=errors, warnings=warnings)
