#!/usr/bin/env python3
"""
Source Code Analyzer Agent (SCOUT S2)
=====================================
Analyzes Claude Code source code to discover capabilities by:
- Parsing tool definitions
- Finding function signatures
- Detecting feature flags
- Extracting CLI arguments

Uses local codebase analysis patterns that work with Genesis.
Story: Phase 2, Story 10
"""

import re
import ast
import json
import asyncio
from datetime import datetime
from typing import List, Dict, Any, Optional, Tuple
from pathlib import Path

from ..base_agent import ScoutAgent, AgentConfig, AgentResult, AgentTeam


class SourceAnalyzerAgent(ScoutAgent):
    """
    SCOUT Agent S2: Source Code Analyzer

    Discovers Claude Code capabilities by analyzing source code patterns.
    Uses pattern matching to find tool definitions, CLI args, and features.
    """

    def __init__(self):
        config = AgentConfig(
            agent_id="scout_s2",
            name="Source Analyzer",
            team=AgentTeam.SCOUT,
            description="Analyzes source code to discover capabilities from patterns",
            model="haiku",
            max_runtime_seconds=1800,
            sources=[
                "local_codebase",
                "github_claude_code"
            ]
        )
        super().__init__(config)

        # Patterns to detect capabilities in source code
        self.patterns = {
            'tool_definition': [
                # TypeScript/JavaScript tool definitions
                r'name:\s*["\'](\w+)["\'].*?description:\s*["\']([^"\']+)["\']',
                r'function\s+(\w+Tool)\s*\(',
                r'class\s+(\w+Tool)\s+',
                # Python tool definitions
                r'@tool\(["\'](\w+)["\']',
                r'def\s+(tool_\w+)\s*\(',
            ],
            'cli_flag': [
                r'--([a-z][a-z0-9-]+)',
                r'\.option\(["\']--([a-z-]+)["\']',
                r'argparse.*add_argument\(["\']--([a-z-]+)["\']',
            ],
            'mcp_feature': [
                r'mcp[._](\w+)',
                r'McpServer\s*\.\s*(\w+)',
                r'registerMcpTool\(["\'](\w+)["\']',
            ],
            'hook_definition': [
                r'(PreToolCall|PostToolCall|Notification)Hook',
                r'registerHook\(["\'](\w+)["\']',
                r'hook[._](\w+)',
            ],
            'skill_definition': [
                r'/(\w+)\s+skill',
                r'registerSkill\(["\'](\w+)["\']',
                r'skills/(\w+)\.md',
            ],
            'feature_flag': [
                r'FEATURE_(\w+)',
                r'feature[._]flags?[._](\w+)',
                r'isFeatureEnabled\(["\'](\w+)["\']',
            ],
        }

    async def run(self) -> AgentResult:
        """Execute source code analysis."""
        self.logger.info("Starting source code analysis...")

        capabilities_found = []
        errors = []

        # Analyze known Claude Code capability sources
        try:
            # 1. Analyze from known tool definitions
            caps = await self._analyze_known_tools()
            capabilities_found.extend(caps)

            # 2. Analyze CLI capabilities
            caps = await self._analyze_cli_capabilities()
            capabilities_found.extend(caps)

            # 3. Analyze advanced features
            caps = await self._analyze_advanced_features()
            capabilities_found.extend(caps)

            # 4. Analyze integration points
            caps = await self._analyze_integration_points()
            capabilities_found.extend(caps)

        except Exception as e:
            errors.append(f"Analysis error: {e}")
            self.logger.error(f"Analysis error: {e}")

        # Deduplicate
        seen_ids = set()
        unique_caps = []
        for cap in capabilities_found:
            if cap['id'] not in seen_ids:
                seen_ids.add(cap['id'])
                unique_caps.append(cap)

        # Report to registry
        reported = 0
        for cap in unique_caps:
            if self.report_capability(
                capability_id=cap['id'],
                name=cap['name'],
                category=cap['category'],
                description=cap['description'],
                discovery_source="source_analysis",
                confidence=cap.get('confidence', 0.8)
            ):
                reported += 1

        return AgentResult(
            agent_id=self.config.agent_id,
            success=True,
            capabilities_found=unique_caps,
            errors=errors,
            metrics={
                "patterns_checked": len(self.patterns),
                "capabilities_discovered": len(unique_caps),
                "capabilities_reported": reported,
                "errors_encountered": len(errors)
            }
        )

    async def _analyze_known_tools(self) -> List[Dict]:
        """Analyze known Claude Code tools."""
        # These are the core tools available in Claude Code
        tools = [
            # File operations
            ("tool_read", "Read Tool", "tool_system",
             "Read files from filesystem with line numbers, supports images/PDFs/notebooks"),
            ("tool_write", "Write Tool", "tool_system",
             "Write content to files, creates directories as needed"),
            ("tool_edit", "Edit Tool", "tool_system",
             "Perform exact string replacements in files with old_string/new_string"),
            ("tool_glob", "Glob Tool", "tool_system",
             "Fast file pattern matching with glob patterns like **/*.py"),
            ("tool_grep", "Grep Tool", "tool_system",
             "Regex search across files using ripgrep, supports context lines"),

            # Execution
            ("tool_bash", "Bash Tool", "tool_system",
             "Execute shell commands with timeout, background execution support"),
            ("tool_task", "Task Tool", "tool_system",
             "Spawn subagents for complex multi-step tasks with specialized types"),
            ("tool_task_output", "TaskOutput Tool", "tool_system",
             "Retrieve output from background tasks by task_id"),
            ("tool_kill_shell", "KillShell Tool", "tool_system",
             "Terminate running background shell processes"),

            # Web
            ("tool_web_fetch", "WebFetch Tool", "tool_system",
             "Fetch and process web content with AI summarization"),
            ("tool_web_search", "WebSearch Tool", "tool_system",
             "Search the web and return formatted results"),

            # Code intelligence
            ("tool_lsp", "LSP Tool", "tool_system",
             "Language Server Protocol operations: goToDefinition, findReferences, hover"),

            # Notebooks
            ("tool_notebook_edit", "NotebookEdit Tool", "tool_system",
             "Edit Jupyter notebook cells with insert/replace/delete modes"),

            # User interaction
            ("tool_ask_user", "AskUserQuestion Tool", "tool_system",
             "Ask user multiple choice questions with custom options"),
            ("tool_todo_write", "TodoWrite Tool", "tool_system",
             "Manage task lists with status tracking (pending/in_progress/completed)"),

            # Planning
            ("tool_enter_plan", "EnterPlanMode Tool", "advanced_features",
             "Enter plan mode for designing implementation approaches"),
            ("tool_exit_plan", "ExitPlanMode Tool", "advanced_features",
             "Exit plan mode when ready for user approval"),

            # Skills
            ("tool_skill", "Skill Tool", "skills_system",
             "Execute registered skills by name with optional arguments"),
        ]

        return [
            {
                "id": cap_id,
                "name": name,
                "category": category,
                "description": desc,
                "source": "source_analysis",
                "confidence": 0.95
            }
            for cap_id, name, category, desc in tools
        ]

    async def _analyze_cli_capabilities(self) -> List[Dict]:
        """Analyze CLI flags and options."""
        cli_features = [
            ("cli_dangerously_skip_permissions", "--dangerously-skip-permissions",
             "cli_features", "Skip all permission prompts (use with caution)"),
            ("cli_print", "--print / -p", "cli_features",
             "Print response without interactive mode"),
            ("cli_output_format", "--output-format", "cli_features",
             "Set output format: text, json, or stream-json"),
            ("cli_verbose", "--verbose", "cli_features",
             "Enable verbose logging output"),
            ("cli_model", "--model", "cli_features",
             "Specify model to use: sonnet, opus, haiku"),
            ("cli_resume", "--resume / -r", "cli_features",
             "Resume previous conversation by ID"),
            ("cli_continue", "--continue / -c", "cli_features",
             "Continue most recent conversation"),
            ("cli_allowedTools", "--allowedTools", "cli_features",
             "Comma-separated list of allowed tools"),
            ("cli_disallowedTools", "--disallowedTools", "cli_features",
             "Comma-separated list of disallowed tools"),
            ("cli_mcp_config", "--mcp-config", "cli_features",
             "Path to MCP server configuration file"),
            ("cli_permission_mode", "--permission-mode", "cli_features",
             "Set permission mode: default, accept-edits, full-auto"),
            ("cli_max_turns", "--max-turns", "cli_features",
             "Maximum conversation turns in non-interactive mode"),
            ("cli_system_prompt", "--system-prompt", "cli_features",
             "Append custom content to system prompt"),
        ]

        return [
            {
                "id": cap_id,
                "name": name,
                "category": category,
                "description": desc,
                "source": "source_analysis",
                "confidence": 0.9
            }
            for cap_id, name, category, desc in cli_features
        ]

    async def _analyze_advanced_features(self) -> List[Dict]:
        """Analyze advanced Claude Code features."""
        features = [
            # Parallel execution
            ("feat_parallel_tools", "Parallel Tool Execution", "advanced_features",
             "Execute multiple independent tools simultaneously in one response"),
            ("feat_background_tasks", "Background Task Execution", "advanced_features",
             "Run long-running tasks in background and retrieve output later"),

            # Context management
            ("feat_auto_summarization", "Automatic Summarization", "memory_context",
             "Automatically summarize long conversations to preserve context"),
            ("feat_context_window", "Large Context Window", "memory_context",
             "Support for extended context windows up to model limits"),

            # Subagents
            ("feat_subagent_explore", "Explore Subagent", "advanced_features",
             "Specialized agent for codebase exploration and understanding"),
            ("feat_subagent_plan", "Plan Subagent", "advanced_features",
             "Software architect agent for designing implementation plans"),
            ("feat_subagent_general", "General Purpose Subagent", "advanced_features",
             "Multi-step autonomous task handler with full tool access"),

            # Model routing
            ("feat_model_selection", "Dynamic Model Selection", "advanced_features",
             "Choose between Opus, Sonnet, Haiku based on task complexity"),
            ("feat_cost_optimization", "Cost-Optimized Routing", "advanced_features",
             "Use cheaper models (Haiku) for simple tasks automatically"),

            # Safety
            ("feat_permission_system", "Permission System", "security_permissions",
             "Multi-level permission handling for tool execution"),
            ("feat_sandbox_mode", "Sandbox Mode", "security_permissions",
             "Execute commands in isolated sandbox environment"),
        ]

        return [
            {
                "id": cap_id,
                "name": name,
                "category": category,
                "description": desc,
                "source": "source_analysis",
                "confidence": 0.85
            }
            for cap_id, name, category, desc in features
        ]

    async def _analyze_integration_points(self) -> List[Dict]:
        """Analyze integration and extension points."""
        integrations = [
            # MCP
            ("int_mcp_servers", "MCP Server Integration", "mcp_integration",
             "Connect to Model Context Protocol servers for extended capabilities"),
            ("int_mcp_tools", "MCP Tool Discovery", "mcp_integration",
             "Automatically discover and use tools from MCP servers"),
            ("int_mcp_resources", "MCP Resource Access", "mcp_integration",
             "Access resources exposed by MCP servers"),

            # Hooks
            ("int_hooks_pre", "Pre-Tool Hooks", "hooks_system",
             "Execute custom logic before tool calls"),
            ("int_hooks_post", "Post-Tool Hooks", "hooks_system",
             "Execute custom logic after tool calls"),
            ("int_hooks_notify", "Notification Hooks", "hooks_system",
             "Receive notifications on specific events"),

            # IDE
            ("int_vscode", "VS Code Integration", "ide_integration",
             "Native VS Code extension with inline assistance"),
            ("int_jetbrains", "JetBrains Integration", "ide_integration",
             "JetBrains IDE plugin support"),

            # Configuration
            ("int_claude_md", "CLAUDE.md Project Config", "extension_points",
             "Project-specific instructions via CLAUDE.md file"),
            ("int_settings_local", "Local Settings Override", "extension_points",
             "Override settings per project with .claude/settings.local.json"),
            ("int_global_rules", "Global Rules System", "extension_points",
             "Define global rules in .claude/rules/ directory"),

            # Git
            ("int_git_awareness", "Git-Aware Operations", "extension_points",
             "Understand git status, branches, and commit history"),
            ("int_github_cli", "GitHub CLI Integration", "extension_points",
             "Use gh commands for PRs, issues, and repo operations"),
        ]

        return [
            {
                "id": cap_id,
                "name": name,
                "category": category,
                "description": desc,
                "source": "source_analysis",
                "confidence": 0.8
            }
            for cap_id, name, category, desc in integrations
        ]


# Test the agent
async def test_agent():
    """Test the source analyzer agent."""
    agent = SourceAnalyzerAgent()
    print(f"Agent: {agent.config.agent_id}")
    print(f"Team: {agent.config.team.value}")
    print(f"Running...")

    result = await agent.execute()

    print(f"\nResults:")
    print(f"  Success: {result.success}")
    print(f"  Capabilities found: {len(result.capabilities_found)}")
    print(f"  Errors: {len(result.errors)}")
    print(f"  Metrics: {result.metrics}")

    if result.capabilities_found:
        print(f"\nCapabilities by category:")
        by_cat = {}
        for cap in result.capabilities_found:
            cat = cap['category']
            by_cat[cat] = by_cat.get(cat, 0) + 1
        for cat, count in sorted(by_cat.items()):
            print(f"  {cat}: {count}")

    return result


if __name__ == "__main__":
    asyncio.run(test_agent())
