"""Agent Configuration Manager Service

This service handles agent configuration management including base agent loading,
tool configuration, and agent-specific settings.

Extracted from AgentDeploymentService as part of the refactoring to improve
maintainability and testability.
"""

import json
from pathlib import Path
from typing import Any

from claude_mpm.core.logging_config import get_logger


class AgentConfigurationManager:
    """Service for managing agent configuration and settings.

    This service handles:
    - Base agent loading and parsing
    - Tool configuration for different agent types
    - Agent-specific configuration management
    - Source tier determination and configuration
    """

    def __init__(self, base_agent_path: Path | None = None):
        """Initialize the agent configuration manager.

        Args:
            base_agent_path: Path to the base agent file
        """
        self.logger = get_logger(__name__)
        self.base_agent_path = base_agent_path
        self._base_agent_cache = None  # Cache for base agent data

    def load_base_agent(self) -> tuple[dict, tuple]:
        """
        Load base agent configuration and version.

        Returns:
            Tuple of (base_agent_data, base_agent_version)
        """
        # Return cached data if available
        if self._base_agent_cache is not None:
            return self._base_agent_cache

        if not self.base_agent_path or not self.base_agent_path.exists():
            self.logger.warning(f"Base agent file not found: {self.base_agent_path}")
            # Return minimal default base agent
            default_base_agent = {
                "name": "base-agent",
                "description": "Base agent configuration",
                "version": "1.0.0",
                "instructions": "You are a helpful AI assistant.",
                "tools": ["Read", "Write", "Edit"],
            }
            self._base_agent_cache = (default_base_agent, (1, 0, 0))
            return self._base_agent_cache

        try:
            # Read base agent file
            base_agent_content = self.base_agent_path.read_text()

            # Parse base agent data
            base_agent_data = self._parse_base_agent_content(base_agent_content)

            # Extract version information
            base_agent_version = self._extract_base_agent_version(base_agent_data)

            # Cache the result
            self._base_agent_cache = (base_agent_data, base_agent_version)

            self.logger.debug(f"Loaded base agent from {self.base_agent_path}")
            return self._base_agent_cache

        except Exception as e:
            self.logger.error(f"Failed to load base agent: {e}")
            # Return minimal default on error
            default_base_agent = {
                "name": "base-agent",
                "description": "Base agent configuration (fallback)",
                "version": "1.0.0",
                "instructions": "You are a helpful AI assistant.",
                "tools": ["Read", "Write", "Edit"],
            }
            self._base_agent_cache = (default_base_agent, (1, 0, 0))
            return self._base_agent_cache

    def get_agent_tools(self, agent_name: str, metadata: dict[str, Any]) -> list[str]:
        """
        Get appropriate tools for an agent based on its type and metadata.

        Args:
            agent_name: Name of the agent
            metadata: Agent metadata

        Returns:
            List of tool names
        """
        # Base tools all agents should have
        base_tools = [
            "Read",
            "Write",
            "Edit",
            "MultiEdit",
            "Grep",
            "Glob",
            "LS",
            "TodoWrite",
        ]

        # Agent-specific tools based on name patterns
        agent_tools = {
            # Security agents
            "security": [*base_tools, "SecurityScan", "VulnerabilityCheck"],
            "sec": [*base_tools, "SecurityScan", "VulnerabilityCheck"],
            # QA and testing agents
            "qa": [*base_tools, "TestRunner", "CodeAnalysis"],
            "test": [*base_tools, "TestRunner", "CodeAnalysis"],
            "testing": [*base_tools, "TestRunner", "CodeAnalysis"],
            # Documentation agents
            "doc": [*base_tools, "DocumentGenerator", "MarkdownProcessor"],
            "docs": [*base_tools, "DocumentGenerator", "MarkdownProcessor"],
            "documentation": [*base_tools, "DocumentGenerator", "MarkdownProcessor"],
            # Data processing agents
            "data": [*base_tools, "DataProcessor", "CSVHandler"],
            "analytics": [*base_tools, "DataProcessor", "CSVHandler"],
            # Operations agents
            "ops": [*base_tools, "SystemMonitor", "LogAnalyzer"],
            "operations": [*base_tools, "SystemMonitor", "LogAnalyzer"],
            "monitor": [*base_tools, "SystemMonitor", "LogAnalyzer"],
            # Research agents
            "research": [*base_tools, "WebSearch", "DataCollector"],
            "analysis": [*base_tools, "WebSearch", "DataCollector"],
        }

        # Check agent name for tool assignment
        agent_name_lower = agent_name.lower()
        for pattern, tools in agent_tools.items():
            if pattern in agent_name_lower:
                return tools

        # Check metadata for specializations
        specializations = metadata.get("specializations", [])
        for spec in specializations:
            spec_lower = spec.lower()
            if spec_lower in agent_tools:
                return agent_tools[spec_lower]

        # Return default tools with web search and bash
        return [*base_tools, "Bash", "WebSearch"]

    def get_agent_specific_config(self, agent_name: str) -> dict[str, Any]:
        """
        Get agent-specific configuration based on agent type.

        Args:
            agent_name: Name of the agent

        Returns:
            Dictionary with agent-specific configuration
        """
        agent_name_lower = agent_name.lower()

        # Default configuration
        config = {
            "timeout": 300,  # 5 minutes
            "max_iterations": 10,
            "memory_limit": "1GB",
            "parallel_execution": False,
        }

        # Agent-specific configurations
        if "security" in agent_name_lower or "sec" in agent_name_lower:
            config.update(
                {
                    "timeout": 600,  # Security scans may take longer
                    "max_iterations": 20,
                    "security_mode": True,
                    "audit_logging": True,
                }
            )

        elif "qa" in agent_name_lower or "test" in agent_name_lower:
            config.update(
                {
                    "timeout": 900,  # Tests may take longer
                    "max_iterations": 15,
                    "test_mode": True,
                    "coverage_reporting": True,
                }
            )

        elif "data" in agent_name_lower or "analytics" in agent_name_lower:
            config.update(
                {
                    "timeout": 1200,  # Data processing may take longer
                    "memory_limit": "2GB",
                    "parallel_execution": True,
                    "data_processing_mode": True,
                }
            )

        elif "ops" in agent_name_lower or "monitor" in agent_name_lower:
            config.update(
                {
                    "timeout": 180,  # Operations should be quick
                    "max_iterations": 5,
                    "monitoring_mode": True,
                    "alert_threshold": "warning",
                }
            )

        elif "research" in agent_name_lower:
            config.update(
                {
                    "timeout": 1800,  # Research may take very long
                    "max_iterations": 25,
                    "research_mode": True,
                    "web_search_enabled": True,
                }
            )

        return config

    def determine_source_tier(self) -> str:
        """
        Determine the source tier for agent deployment.

        Returns:
            Source tier string ("system", "user", or "project")
        """
        # For now, this is a simple implementation
        # In the future, this could be enhanced with more sophisticated logic

        # Check if we're in a project context
        current_dir = Path.cwd()

        # Look for project indicators
        project_indicators = [
            ".git",
            "package.json",
            "requirements.txt",
            "Cargo.toml",
            "go.mod",
            "pom.xml",
            "build.gradle",
        ]

        for indicator in project_indicators:
            if (current_dir / indicator).exists():
                return "project"

        # Check for user-specific configuration
        user_config_dir = Path.home() / ".claude"
        if user_config_dir.exists():
            return "user"

        # Default to system tier
        return "system"

    def _parse_base_agent_content(self, content: str) -> dict:
        """
        Parse base agent content from various formats.

        Args:
            content: Base agent file content

        Returns:
            Parsed base agent data
        """
        # Try to parse as JSON first
        try:
            return json.loads(content)
        except json.JSONDecodeError:
            pass

        # Try to parse as Markdown with YAML frontmatter
        if content.strip().startswith("---"):
            try:
                import yaml

                # Split frontmatter and content
                parts = content.split("---", 2)
                if len(parts) >= 3:
                    frontmatter = parts[1].strip()
                    markdown_content = parts[2].strip()

                    # Parse YAML frontmatter
                    data = yaml.safe_load(frontmatter)

                    # Add markdown content as instructions
                    if markdown_content:
                        data["instructions"] = markdown_content

                    return data
            except Exception:
                pass

        # Fallback: treat as plain text instructions
        return {
            "name": "base-agent",
            "description": "Base agent configuration",
            "version": "1.0.0",
            "instructions": content.strip(),
            "tools": ["Read", "Write", "Edit"],
        }

    def _extract_base_agent_version(self, base_agent_data: dict) -> tuple:
        """
        Extract version from base agent data.

        Args:
            base_agent_data: Base agent data dictionary

        Returns:
            Version tuple (major, minor, patch)
        """
        version_str = base_agent_data.get("version", "1.0.0")

        # Parse semantic version
        try:
            import re

            match = re.match(r"^v?(\d+)\.(\d+)\.(\d+)", str(version_str))
            if match:
                return (int(match.group(1)), int(match.group(2)), int(match.group(3)))
        except Exception:
            pass

        # Fallback to default version
        return (1, 0, 0)

    def clear_cache(self):
        """Clear the base agent cache."""
        self._base_agent_cache = None
        self.logger.debug("Base agent cache cleared")

    def get_configuration_summary(self) -> dict[str, Any]:
        """
        Get a summary of the current configuration.

        Returns:
            Dictionary with configuration summary
        """
        base_agent_data, base_agent_version = self.load_base_agent()

        return {
            "base_agent_path": (
                str(self.base_agent_path) if self.base_agent_path else None
            ),
            "base_agent_loaded": self._base_agent_cache is not None,
            "base_agent_version": base_agent_version,
            "base_agent_name": base_agent_data.get("name", "unknown"),
            "source_tier": self.determine_source_tier(),
            "cache_status": "loaded" if self._base_agent_cache else "empty",
        }
