"""
Strategic Pipeline Registry - Default LLM Assistance Configuration for Aperion.

Provides intelligent defaults for LLM assistance across key operational pipelines:
- Testing pipelines (pre-validate inputs, diagnose failures)
- Deployment pipelines (validate configs, analyze outputs)
- Monitoring pipelines (enrich alerts, diagnose issues)

All configurations are opt-in and can be overridden per pipeline.
"""

from dataclasses import dataclass
from enum import Enum
from typing import Any, Optional

from .pipeline import LLMAssistanceConfig, LLMAssistanceMode


class PipelineCategory(Enum):
    """Strategic pipeline categories for Aperion operations."""

    TESTING = "testing"  # Test execution, validation, coverage analysis
    DEPLOYMENT = (
        "deployment"  # Config validation, dependency checks, health verification
    )
    MONITORING = "monitoring"  # Metrics analysis, alert enrichment, anomaly detection
    CODE_ANALYSIS = "code_analysis"  # Lint diagnosis, security scans, quality checks
    DATA_PROCESSING = "data_processing"  # ETL, validation, transformation
    REPORTING = "reporting"  # Report generation, summarization, insights
    MAINTENANCE = "maintenance"  # Cleanup, optimization, health checks
    INTEGRATION = "integration"  # API integration, data sync, cross-system ops


@dataclass
class StrategicPipelineConfig:
    """Configuration for a strategic pipeline with recommended LLM assistance."""

    name: str
    category: PipelineCategory
    description: str
    recommended_modes: list[LLMAssistanceMode]
    default_timeout: float = 10.0
    cache_enabled: bool = True
    fallback_on_error: bool = True
    priority: int = 5  # 1-10, higher = more critical
    metadata: dict[str, Any] | None = None


class StrategicPipelineRegistry:
    """
    Registry of strategic pipelines with intelligent LLM assistance defaults.

    Provides sensible defaults while allowing opt-out or customization.
    """

    def __init__(self):
        """Initialize the registry with strategic pipelines."""
        self._pipelines: dict[str, StrategicPipelineConfig] = {}
        self._register_defaults()

    def _register_defaults(self):
        """Register default strategic pipelines for Aperion operations."""

        # TESTING PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="pytest_execution",
                category=PipelineCategory.TESTING,
                description="Execute pytest test suites with intelligent failure diagnosis",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Validate test setup
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Diagnose failures
                ],
                priority=9,  # High priority - developer workflow
                metadata={
                    "use_cases": ["unit tests", "integration tests", "e2e tests"],
                    "benefits": ["faster debugging", "root cause analysis"],
                },
            )
        )

        self.register(
            StrategicPipelineConfig(
                name="coverage_analysis",
                category=PipelineCategory.TESTING,
                description="Analyze test coverage and identify gaps",
                recommended_modes=[
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Explain coverage gaps
                    LLMAssistanceMode.ENRICH_CONTEXT,  # Suggest missing tests
                ],
                priority=7,
                metadata={
                    "coverage_threshold": 0.95,
                    "focus_areas": ["critical paths"],
                },
            )
        )

        self.register(
            StrategicPipelineConfig(
                name="test_quality_validation",
                category=PipelineCategory.TESTING,
                description="Validate test quality (assertions, coverage, determinism)",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Check test structure
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Quality metrics analysis
                ],
                priority=6,
            )
        )

        # DEPLOYMENT PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="pre_deployment_validation",
                category=PipelineCategory.DEPLOYMENT,
                description="Validate configurations, dependencies, and environment before deploy",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Validate configs
                    LLMAssistanceMode.ENRICH_CONTEXT,  # Add deployment insights
                ],
                priority=10,  # Critical - prevent bad deploys
                metadata={
                    "checks": [
                        "config validation",
                        "dependency compatibility",
                        "env vars",
                    ],
                    "blocking": True,
                },
            )
        )

        self.register(
            StrategicPipelineConfig(
                name="dependency_resolution",
                category=PipelineCategory.DEPLOYMENT,
                description="Resolve and validate Python package dependencies",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Check for conflicts
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Diagnose resolution failures
                ],
                priority=9,
                metadata={
                    "python_version": "3.12+",
                    "package_managers": ["pip", "uv"],
                },
            )
        )

        self.register(
            StrategicPipelineConfig(
                name="post_deployment_health",
                category=PipelineCategory.DEPLOYMENT,
                description="Verify system health after deployment",
                recommended_modes=[
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Analyze health metrics
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Diagnose health issues
                ],
                priority=10,
                metadata={"health_endpoints": ["/healthz", "/readyz"]},
            )
        )

        # MONITORING PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="metrics_analysis",
                category=PipelineCategory.MONITORING,
                description="Analyze system metrics and detect anomalies",
                recommended_modes=[
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Explain trends
                    LLMAssistanceMode.ENRICH_CONTEXT,  # Add context to anomalies
                ],
                priority=8,
                metadata={
                    "metrics": ["response_time", "error_rate", "throughput"],
                    "baseline_window": "7d",
                },
            )
        )

        self.register(
            StrategicPipelineConfig(
                name="alert_enrichment",
                category=PipelineCategory.MONITORING,
                description="Enrich alerts with context and recommended actions",
                recommended_modes=[
                    LLMAssistanceMode.ENRICH_CONTEXT,  # Add alert context
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Diagnose root cause
                ],
                priority=9,
                metadata={"alert_channels": ["pagerduty", "slack", "email"]},
            )
        )

        self.register(
            StrategicPipelineConfig(
                name="log_analysis",
                category=PipelineCategory.MONITORING,
                description="Analyze logs for patterns, errors, and insights",
                recommended_modes=[
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Identify patterns
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Diagnose errors
                ],
                priority=7,
                metadata={"log_sources": ["fsal", "gateway", "eventbus"]},
            )
        )

        # CODE ANALYSIS PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="lint_diagnosis",
                category=PipelineCategory.CODE_ANALYSIS,
                description="Diagnose linting errors with intelligent recommendations",
                recommended_modes=[
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Explain lint errors
                    LLMAssistanceMode.ENRICH_CONTEXT,  # Suggest fixes
                ],
                priority=6,
                metadata={
                    "linters": ["ruff", "black", "flake8", "bandit"],
                    "auto_fix": False,
                },
            )
        )

        self.register(
            StrategicPipelineConfig(
                name="security_scan",
                category=PipelineCategory.CODE_ANALYSIS,
                description="Scan code for security vulnerabilities",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Validate scan config
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Explain vulnerabilities
                ],
                priority=10,
                metadata={
                    "scanners": ["bandit", "semgrep", "trivy"],
                    "severity_threshold": "medium",
                },
            )
        )

        # DATA PROCESSING PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="data_validation",
                category=PipelineCategory.DATA_PROCESSING,
                description="Validate data quality and schema compliance",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Validate schema
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Diagnose validation failures
                ],
                priority=8,
                metadata={
                    "validation_rules": ["schema", "constraints", "business_rules"]
                },
            )
        )

        # REPORTING PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="report_generation",
                category=PipelineCategory.REPORTING,
                description="Generate intelligent reports with insights",
                recommended_modes=[
                    LLMAssistanceMode.ENRICH_CONTEXT,  # Add insights
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Summarize findings
                ],
                priority=5,
                metadata={"report_types": ["coverage", "performance", "security"]},
            )
        )

        # MAINTENANCE PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="database_maintenance",
                category=PipelineCategory.MAINTENANCE,
                description="Perform database maintenance and optimization",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Validate maintenance plan
                    LLMAssistanceMode.ANALYZE_OUTPUT,  # Analyze results
                ],
                priority=7,
                metadata={"operations": ["vacuum", "reindex", "analyze"]},
            )
        )

        # INTEGRATION PIPELINES
        self.register(
            StrategicPipelineConfig(
                name="api_integration",
                category=PipelineCategory.INTEGRATION,
                description="Integrate with external APIs and handle data sync",
                recommended_modes=[
                    LLMAssistanceMode.PRE_VALIDATE,  # Validate API contracts
                    LLMAssistanceMode.ERROR_DIAGNOSIS,  # Diagnose integration failures
                ],
                priority=8,
                metadata={
                    "apis": ["external_service"],
                    "retry_strategy": "exponential_backoff",
                },
            )
        )

    def register(self, config: StrategicPipelineConfig):
        """Register a strategic pipeline configuration."""
        self._pipelines[config.name] = config

    def get(self, name: str) -> Optional[StrategicPipelineConfig]:
        """Get configuration for a strategic pipeline."""
        return self._pipelines.get(name)

    def get_by_category(
        self, category: PipelineCategory
    ) -> list[StrategicPipelineConfig]:
        """Get all pipelines in a category."""
        return [cfg for cfg in self._pipelines.values() if cfg.category == category]

    def list_all(self) -> list[StrategicPipelineConfig]:
        """List all registered strategic pipelines."""
        return list(self._pipelines.values())

    def get_llm_config(
        self,
        pipeline_name: str,
        mode: LLMAssistanceMode,
        enabled: bool = True,
        **kwargs,
    ) -> LLMAssistanceConfig:
        """
        Get LLM assistance configuration for a pipeline stage.

        Args:
            pipeline_name: Name of the strategic pipeline
            mode: LLM assistance mode to use
            enabled: Whether LLM assistance is enabled
            **kwargs: Override default configuration

        Returns:
            LLM assistance configuration with intelligent defaults
        """
        config = self.get(pipeline_name)

        # Default configuration
        defaults = {
            "timeout": 10.0,
            "cache_results": True,
            "fallback_on_error": True,
        }

        # Apply strategic defaults if available
        if config:
            defaults["timeout"] = config.default_timeout
            defaults["cache_results"] = config.cache_enabled
            defaults["fallback_on_error"] = config.fallback_on_error

            # Add pipeline metadata
            metadata = kwargs.pop("metadata", {})
            if config.metadata:
                metadata.update(config.metadata)
            metadata["pipeline_name"] = pipeline_name
            metadata["category"] = config.category.value
            metadata["priority"] = config.priority
            kwargs["metadata"] = metadata

        # Apply user overrides
        timeout = kwargs.pop("timeout", defaults["timeout"])
        cache_results = kwargs.pop("cache_results", defaults["cache_results"])
        fallback_on_error = kwargs.pop(
            "fallback_on_error", defaults["fallback_on_error"]
        )

        return LLMAssistanceConfig(
            mode=mode,
            enabled=enabled,
            timeout=timeout,
            cache_results=cache_results,
            fallback_on_error=fallback_on_error,
            **kwargs,
        )

    def is_strategic(self, pipeline_name: str) -> bool:
        """Check if a pipeline is strategic (has default LLM config)."""
        return pipeline_name in self._pipelines

    def get_recommended_modes(self, pipeline_name: str) -> list[LLMAssistanceMode]:
        """Get recommended LLM assistance modes for a pipeline."""
        config = self.get(pipeline_name)
        return config.recommended_modes if config else []

    def get_statistics(self) -> dict[str, Any]:
        """Get registry statistics."""
        total = len(self._pipelines)
        by_category = {}
        by_priority = {}

        for config in self._pipelines.values():
            # Count by category
            cat = config.category.value
            by_category[cat] = by_category.get(cat, 0) + 1

            # Count by priority range
            priority_range = (
                f"{(config.priority // 3) * 3 + 1}-{(config.priority // 3) * 3 + 3}"
            )
            by_priority[priority_range] = by_priority.get(priority_range, 0) + 1

        return {
            "total_pipelines": total,
            "by_category": by_category,
            "by_priority": by_priority,
            "categories": [cat.value for cat in PipelineCategory],
            "assistance_modes": [mode.value for mode in LLMAssistanceMode],
        }


# Global registry instance
_registry = None


def get_registry() -> StrategicPipelineRegistry:
    """Get the global strategic pipeline registry."""
    global _registry
    if _registry is None:
        _registry = StrategicPipelineRegistry()
    return _registry
