"""
Constants and templates for KEN-MCP server generator
All hardcoded strings and templates extracted from generator.py
"""

# File content templates
GITIGNORE_TEMPLATE = """__pycache__/
*.py[cod]
.env
.venv/
venv/
*.log
.DS_Store
"""

ENV_EXAMPLE_TEMPLATE = """# Environment variables for MCP server
# Copy this file to .env and fill in your actual values

# API Keys
# OPENAI_API_KEY=your_openai_api_key_here
# ANTHROPIC_API_KEY=your_anthropic_api_key_here
# GOOGLE_API_KEY=your_google_api_key_here

# Database Configuration
# DATABASE_URL=postgresql://user:password@localhost:5432/dbname
# REDIS_URL=redis://localhost:6379

# External Service URLs
# API_BASE_URL=https://api.example.com
# WEBHOOK_URL=https://your-webhook-endpoint.com

# Authentication
# AUTH_TOKEN=your_auth_token_here
# CLIENT_ID=your_client_id_here
# CLIENT_SECRET=your_client_secret_here

# Feature Flags
# DEBUG_MODE=false
# ENABLE_LOGGING=true

# Rate Limiting
# RATE_LIMIT_REQUESTS=100
# RATE_LIMIT_WINDOW=3600

# Custom Configuration
# Add your own environment variables below:
"""

# Server code templates
SERVER_HEADER_TEMPLATE = '''#!/usr/bin/env python3
"""
{description}
Generated by KEN-MCP on {date}

TODO: Claude, please customize this MCP server based on these requirements:
{requirements}

Instructions:
1. Rename the placeholder tools to match the actual functionality needed
2. Update tool descriptions and parameters based on requirements
3. Implement the actual logic in each tool function
4. Add/remove tools, resources, and prompts as needed
5. Update dependencies in pyproject.toml if additional packages are required

IMPORTANT: If the MCP fails to load in Claude:
- Run: python scripts/diagnose.py to check for common issues
- Never use print() statements - use logger.info() instead
- Ensure all output goes to stderr, not stdout
"""

{imports}

# CRITICAL: Configure logging to use stderr ONLY - stdout is reserved for MCP protocol
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    stream=sys.stderr  # All logs MUST go to stderr, never stdout!
)
logger = logging.getLogger(__name__)

{env_loading}# Initialize the MCP server with clean stdout (no redirection needed)
mcp = FastMCP(
    name="{project_name}",
    instructions="""
    {description}
    
    Original Requirements:
    {requirements}
    
    TODO: Claude should update these instructions based on the actual implementation.
    """
)

# IMPORTANT: NEVER use print() statements!
# Use logger.info(), logger.debug(), etc. instead
# Any output to stdout will break the MCP protocol

'''

# Tool implementation templates
TOOL_BOILERPLATE_TEMPLATE = '''    # TODO: Claude, implement this tool based on the requirements in the docstring above
    # Consider:
    # - What data sources or APIs might be needed
    # - What processing or transformations are required
    # - What error cases should be handled
    # - What progress updates would be helpful
    
    try:
        # FastMCP Context Methods Reference:
        # - await ctx.info("message") - Log information
        # - await ctx.report_progress(current, total, "message") - Show progress
        # - await ctx.read_resource("uri") - Read from a resource
        
        await ctx.info(f"Starting {tool_name}...")
        
        # TODO: Add parameter validation
        # Example patterns:
        # if not input_data:
        #     raise ToolError("input_data is required")
        # 
        # if not isinstance(input_data, str):
        #     raise ToolError("input_data must be a string")
        #
        # if len(input_data) > 1000:
        #     raise ToolError("input_data too long (max 1000 chars)")
        
        # TODO: Implement the main functionality
        # Common patterns by use case:
        #
        # For data storage:
        #   storage_dir = Path.home() / ".mcp_data" / "{tool_name}"
        #   storage_dir.mkdir(parents=True, exist_ok=True)
        #
        # For API calls:
        #   import httpx
        #   async with httpx.AsyncClient() as client:
        #       response = await client.get(url)
        #
        # For file processing:
        #   from pathlib import Path
        #   file = Path(file_path)
        #   if not file.exists():
        #       raise ToolError(f"File not found: {{file_path}}")
        
        # TODO: Add progress updates for long operations
        # await ctx.report_progress(25, 100, "Loading data...")
        # await ctx.report_progress(50, 100, "Processing...")
        # await ctx.report_progress(75, 100, "Finalizing...")
        
        # TODO: Return appropriate result
        # Success pattern:
        # return {{
        #     "success": True,
        #     "data": processed_data,
        #     "count": len(results),
        #     "message": "Operation completed successfully"
        # }}
        
        result = {{
            "status": "not_implemented",
            "message": f"TODO: Implement {tool_name}",
            "tool": "{tool_name}",
            "description": {tool_desc},
            "input": locals()  # Shows all parameters for debugging
        }}
        
        await ctx.info(f"{tool_name} completed")
        return result
        
    except Exception as e:
        # Always use ToolError for user-facing errors
        raise ToolError(f"{tool_name} error: {{str(e)}}")
'''

TOOL_FALLBACK_TEMPLATE = '''    try:
        from datetime import datetime
        import json
        {param_validation}
        
        await ctx.info(f"Executing {tool_name}...")
        
        # Implementation based on tool purpose
        result = {{
            "tool": "{tool_name}",
            "description": {tool_desc},
            "status": "success",
            "message": "Tool executed successfully",
            "timestamp": datetime.now().isoformat()
        }}
        
        # Add input parameters to result
        for param_name, param_value in locals().items():
            if param_name not in ['ctx', 'result'] and not param_name.startswith('_'):
                result[f"input_{{param_name}}"] = param_value
        
        return result
        
    except Exception as e:
        raise ToolError(f"Failed to execute {tool_name}: {{str(e)}}")
'''

# Resource and prompt templates
RESOURCE_TEMPLATE = '''
@mcp.resource("{uri}")
async def resource_{resource_name}({params_str}) -> List[Dict[str, Any]]:
    """{description}"""
    # TODO: Implement this resource based on requirements
    # Consider what data should be exposed here
    return [{{
        "status": "not_implemented", 
        "message": "TODO: Implement resource for {uri}",
        "description": "{description}"
    }}]
'''

PROMPT_TEMPLATE = '''
@mcp.prompt
def {prompt_name}({params_str}) -> str:
    """{description}"""
    # TODO: Implement this prompt based on requirements
    # Return a string that will be converted to a user message
    # or return a PromptMessage object for more control
    return f"TODO: Implement {prompt_name} prompt - {{locals()}}"
'''

# PyProject template
PYPROJECT_TEMPLATE = """[project]
name = "{project_name}"
version = "0.1.0"
description = "{description}"
readme = "README.md"
requires-python = ">={python_version}"
dependencies = {dependencies}

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["."]
"""

# Documentation templates
README_TEMPLATE = """# {project_name}

{description}

## Installation

Install the required dependencies:

```bash
pip install -r requirements.txt
```

## Usage

Add this MCP server to Claude Code (Global access - recommended):

```bash
claude mcp add {project_name} -s user "/path/to/run_server.py"
```

Alternative (Local access - only works from current directory):
```bash
claude mcp add {project_name} "/path/to/run_server.py"
```

See `help.md` for detailed setup and troubleshooting instructions.

## Documentation

- **Setup Guide**: See `help.md` for comprehensive setup instructions
- **Troubleshooting**: See `help.md` for common issues and solutions
- **Diagnostics**: Run `python scripts/diagnose.py` if the MCP fails to load
- **MCP Protocol**: https://modelcontextprotocol.io

---
Generated by KEN-MCP
"""

# Test file header template
TEST_FILE_HEADER = '''#!/usr/bin/env python3
"""
Automated test suite for {project_name} MCP server
Generated by KEN-MCP

INSTRUCTIONS FOR CLAUDE:
1. Run this test file immediately: python scripts/test.py
2. If import errors occur, run diagnostics first: python scripts/diagnose.py
3. Fix any failing tests in server.py
4. After tests pass, run: python scripts/verify.py
5. Fix all placeholder code and TODOs identified by verify.py
6. Add domain-specific test cases based on the requirements
7. Ensure all tests pass AND verification succeeds before considering the MCP complete

IMPORTANT: These tests verify API structure, not actual implementation!
The verify.py script checks for placeholder code that needs real implementation.

TROUBLESHOOTING:
- Import errors? Run: python scripts/diagnose.py
- Tests fail? Check if server.py has print() statements (use logger instead)
- Still issues? The scripts/diagnose.py script will identify common problems

Original Requirements:
{requirements}
"""

import asyncio
import json
import sys
from pathlib import Path

# Add the parent directory to the path so we can import the server
sys.path.insert(0, str(Path(__file__).parent))

# Import the generated server
try:
    from server import mcp
except ImportError as e:
    # DO NOT use print() in MCP servers - it breaks the protocol
    # Log to stderr instead
    import sys
    sys.stderr.write(f"❌ Failed to import server: {{e}}\\n")
    sys.stderr.write("Make sure server.py exists and has no syntax errors\\n")
    sys.exit(1)
'''

# Error messages
ERROR_MESSAGES = {
    "file_not_found": "File not found: {file_path}",
    "invalid_url": "Invalid URL: {url} must start with http:// or https://",
    "invalid_type": "Invalid {param_name}: must be a valid {expected_type}",
    "parameter_required": "{param_name} is required",
    "value_too_long": "{param_name} too long (max {max_length} chars)",
    "import_failed": "Failed to import server: {error}",
    "syntax_error": "Syntax error in server.py: {error}",
    "test_failed": "{test_name} test failed: {error}",
    "generation_failed": "Failed to generate MCP server: {error}",
    "tool_error": "{tool_name} error: {error}"
}

# Progress messages
PROGRESS_MESSAGES = {
    "analyzing": "Analyzing requirements...",
    "creating_structure": "Creating project structure...",
    "generating_server": "Generating server code...",
    "creating_docs": "Creating documentation...",
    "generating_tests": "Generating test suite...",
    "validating": "Validating project...",
    "complete": "Generation complete!"
}

# Log messages
LOG_MESSAGES = {
    "starting_generation": "🚀 Starting MCP generation for: {project_name}",
    "analyzing_requirements": "📋 Creating boilerplate structure for Claude to customize...",
    "creating_project": "📁 Creating project structure...",
    "generating_code": "💻 Generating server code...",
    "generating_docs": "📚 Generating documentation...",
    "generating_tests": "🧪 Generating test suite...",
    "validating_project": "✔️ Validating project...",
    "project_created": "✅ Created project at: {project_path}",
    "plan_created": "✅ Boilerplate plan created with {tool_count} placeholder tools",
    "server_generated": "✅ Generated server.py and pyproject.toml",
    "docs_generated": "✅ Generated documentation files",
    "tests_generated": "✅ Generated test.py with comprehensive test suite"
}

# Keywords for domain detection
DOMAIN_KEYWORDS = {
    "cooking": ["recipe", "cook", "ingredient", "meal"],
    "task_management": ["task", "todo", "project", "deadline"],
    "monitoring": ["monitor", "track", "watch", "alert"],
    "api_integration": ["api", "endpoint", "rest", "http"],
    "file_processing": ["file", "document", "pdf", "csv"],
    "database": ["database", "sql", "query", "table"],
    "web_scraping": ["scrape", "web", "html", "crawl"],
    "crypto": ["crypto", "bitcoin", "ethereum", "price"],
    "ml_ai": ["classify", "predict", "analyze", "nlp"],
    "realtime": ["websocket", "real-time", "streaming", "live"],
    "auth": ["oauth", "auth", "login", "token"],
    "data_science": ["numpy", "pandas", "matplotlib", "chart"],
    "machine_learning": ["machine learning", "ml", "prediction", "model"]
}

# Dependency suggestions by domain
DEPENDENCY_SUGGESTIONS = {
    "api_http": ["httpx", "requests"],
    "web_scraping": ["beautifulsoup4", "requests", "lxml"],
    "data_processing": ["pandas", "openpyxl"],
    "database": ["sqlalchemy", "psycopg2", "pymysql"],
    "pdf": ["pypdf2"],
    "image": ["pillow"],
    "markdown": ["markdown"],
    "crypto": ["ccxt", "yfinance"],
    "ml_ai": ["scikit-learn", "nltk", "spacy"],
    "websocket": ["websockets", "asyncio"],
    "auth": ["authlib", "oauthlib"],
    "discord": ["discord.py"],
    "slack": ["slack-sdk"],
    "github": ["PyGithub"],
    "data_science": ["numpy", "pandas", "matplotlib"],
    "machine_learning": ["scikit-learn", "joblib"],
    "xml": ["xmltodict"]
}

# Default tool names by position
DEFAULT_TOOL_NAMES = {
    0: {
        "recipe": ["add_recipe", "create_recipe", "save_recipe"],
        "task": ["create_task", "add_todo", "new_task"],
        "monitor": ["start_monitor", "add_monitor", "track_item"],
        "default": ["create_item", "add_entry", "initialize"]
    },
    1: {
        "recipe": ["list_recipes", "search_recipes", "get_recipe"],
        "task": ["list_tasks", "get_tasks", "show_todos"],
        "default": ["list_items", "search_data", "query_items"]
    },
    2: {
        "recipe": ["update_recipe", "rate_recipe", "categorize_recipe"],
        "task": ["complete_task", "update_task", "mark_done"],
        "default": ["update_item", "process_data", "modify_entry"]
    }
}

# Standard library modules (don't need to be installed)
STDLIB_MODULES = {
    "pathlib", "json", "typing", "os", "datetime", 
    "subprocess", "shlex", "platform", "asyncio",
    "stat", "re", "sys"
}

# Default Python version
DEFAULT_PYTHON_VERSION = "3.10"

# Limits from CLAUDE.md
MAX_LINE_LENGTH = 120
MAX_PARAMS_PER_FUNCTION = 4
MAX_LINES_PER_FILE = 300
MAX_NESTING_LEVELS = 4
MAX_DOCSTRING_LENGTH = 500

# Test constants
TEST_MOCK_CONTEXT = '''# Test utilities
class MockContext:
    """Mock context for testing MCP tools"""
    def __init__(self):
        self.logs = []
        self.progress = []
    
    async def info(self, msg):
        self.logs.append(msg)
    
    async def report_progress(self, current, total, msg):
        self.progress.append((current, total, msg))
    
    async def read_resource(self, uri):
        return {"uri": uri, "content": "mock resource content"}
'''

# Help documentation sections
HELP_QUICK_START = """# {project_name} - Cross-Platform Setup & Troubleshooting Guide

## 🚀 Universal Quick Start (All Operating Systems)

### Step 1: Run Cross-Platform Diagnostics
```bash
# Navigate to the root directory (not the project folder)
cd {project_path}/..
python3 scripts/diagnose.py
```
**This will detect your OS and provide platform-specific instructions!**

### Step 2: Install Dependencies

#### Windows:
```cmd
cd {project_path}
py -m pip install -r requirements.txt
# OR
python -m pip install -r requirements.txt
```

#### macOS:
```bash
cd {project_path}
python3 -m pip install -r requirements.txt
# OR
pip3 install -r requirements.txt
```

#### Linux:
```bash
cd {project_path}
# Modern Linux (Ubuntu 22.04+, Debian 12+) requires --break-system-packages
python3 -m pip install --user --break-system-packages -r requirements.txt

# Alternative methods if above fails:
# Method 1: Virtual environment (recommended for development)
# python3 -m venv venv && source venv/bin/activate && pip install -r requirements.txt

# Method 2: System packages (if available)
# sudo apt install python3-fastmcp python3-httpx python3-pydantic

# Method 3: Just --user flag (older Linux)
# python3 -m pip install --user -r requirements.txt
```

### Step 3: Test the MCP Works
```bash
# From root directory
python3 scripts/test.py    # macOS/Linux
py scripts/test.py         # Windows
```
Expected: All tests should pass ✅

### Step 4: Verify Implementation Completeness
```bash
# From root directory
python3 scripts/verify.py  # macOS/Linux
py scripts/verify.py       # Windows
```
This checks for:
- ❌ TODO/FIXME comments that need addressing
- ❌ Placeholder/mock data that needs real implementation
- ❌ Missing directories or configuration files
- ❌ Hardcoded values that should be dynamic
- ❌ Empty function implementations

**IMPORTANT:** Fix all issues identified before proceeding! The MCP won't work properly with placeholder code.

**📋 CLAUDE.md Rules File:** A comprehensive CLAUDE.md file has been generated in the parent directory with:
- Complete MCP and FastMCP fundamentals
- Critical protocol rules and implementation guidelines  
- Project-specific context and requirements
- Debugging workflows and best practices

The CLAUDE.md file is placed in the root directory where Claude Code can find it and helps Claude understand exactly how to work with your MCP!

### Step 5: Add to Claude Code

#### Windows:
```cmd
# Primary method (Global - recommended):
claude mcp add {project_name} -s user "py {project_path}\\run_server.py"

# Alternative methods:
claude mcp add {project_name} -s user "{project_path}\\run_server.bat"
claude mcp add {project_name} -s user "python {project_path}\\run_server.py"

# Local scope (only works from current directory):
# claude mcp add {project_name} "py {project_path}\\run_server.py"
```

#### macOS/Linux:
```bash
# Primary method (Global - recommended):
claude mcp add {project_name} -s user "{project_path}/run_server.py"

# Alternative methods:
claude mcp add {project_name} -s user "python3 {project_path}/run_server.py"
claude mcp add {project_name} -s user "{project_path}/run_server.sh"

# Local scope (only works from current directory):
# claude mcp add {project_name} "{project_path}/run_server.py"
```

### Step 6: Confirm MCP Added
```bash
claude mcp list
# Should show your MCP in the list (may show as "Inactive" before restart)
```

### Step 7: Restart Claude Code
**CRITICAL:** Exit Claude Code completely and restart:
```bash
# Type 'exit' or press Ctrl+C, then run:
claude
```

### Step 8: Verify Connection Status
```bash
claude mcp list
# Should show: ✓ {project_name}    Active (not ✗ Failed)

# In Claude Code, use:
/mcp
# Should show your MCP as connected ✔
```

### Step 9: Use Your MCP
Your MCP tools are now available in Claude Code conversations!

---

## 🔍 Understanding MCP Status

### `claude mcp list` Status Indicators:
- **✓ {project_name}    Active** - MCP is running correctly ✅
- **✗ {project_name}    Failed** - MCP failed to start ❌
- **{project_name}    Inactive** - MCP added but not started (restart needed)

### Status Troubleshooting:
- **Active ✓**: Everything working - MCP tools available in conversations
- **Failed ✗**: See troubleshooting section below
- **Inactive**: Restart Claude Code to activate

---

## 🆘 Quick Troubleshooting

### If MCP Shows as "Failed ✗":
1. **Run diagnostics:** `python3 scripts/diagnose.py` (shows OS-specific fixes)
2. **Check Python:** Make sure you have Python 3.8+ installed
3. **Try alternative commands:** Use the backup methods from Step 4
4. **Check paths:** Ensure all file paths are correct for your OS
5. **Restart required:** Always restart Claude Code after changes

### Platform-Specific Issues:

#### Windows:
- Install Python from python.org or Microsoft Store
- Use `py` command instead of `python3`
- Use backslashes `\\` in paths
- Try running as Administrator if permissions fail

#### macOS:
- Install Python via Homebrew: `brew install python@3.10`
- Use forward slashes `/` in paths  
- Make sure scripts are executable: `chmod +x run_server.py`

#### Linux:
- Install Python: `sudo apt install python3.10` (Ubuntu/Debian)
- Use forward slashes `/` in paths
- Make sure scripts are executable: `chmod +x run_server.py`
- Modern Linux requires `--user` flag: `pip install --user -r requirements.txt`
- If you see "externally-managed-environment" error, use the --user flag
- Check firewall/permissions if issues persist

---

## 📱 Need Help?

**Run the diagnostic tool - it detects your exact setup:**
```bash
python3 scripts/diagnose.py
```

This provides customized instructions for your operating system and Python installation!"""

HELP_TESTING_SECTION = """### Testing the MCP Server
```bash
cd {project_path}

# Run the automated test suite (from root directory)
cd {project_path}/..
python3 scripts/test.py

# Expected output:
# ==================================================
# 🧪 Running MCP Server Tests for {project_name}
# ==================================================
# Testing server initialization...
#   ✅ Server initialization test passed
# Testing tool_one...
#   ✅ Valid input test passed
# ... more tests ...
# ==================================================
# 📊 Test Summary: X/Y passed
# ==================================================
# ✅ All tests passed! The MCP server is ready to use.
```

If any tests fail:
1. Check the error messages in the test output
2. Fix the implementation in server.py
3. Run the tests again until all pass

### Manual Testing
```bash
# Test the server directly (for debugging)
python3 server.py
# Expected output: "Server started on stdio"
# Press Ctrl+C to stop
```"""

# Verification template
VERIFICATION_TEMPLATE = r'''#!/usr/bin/env python3
"""
Implementation Verification for {project_name}
Checks for incomplete implementations and missing requirements

Generated by KEN-MCP
Original Requirements: {requirements}
"""

import re
import sys
import ast
from pathlib import Path
from typing import List, Tuple, Set


class ImplementationVerifier:
    """Verifies that the MCP implementation is complete"""
    
    def __init__(self):
        self.issues = []
        self.warnings = []
        self.checked_files = []
        
        # Patterns that indicate incomplete implementation
        self.todo_patterns = [
            r'TODO:', r'FIXME:', r'XXX:', r'HACK:', r'NOTE:',
            r'TODO\s*\(', r'FIXME\s*\(', r'XXX\s*\('
        ]
        
        self.placeholder_patterns = [
            r'\bmock\b', r'\bdummy\b', r'\btest[_-]data\b', 
            r'\bplaceholder\b', r'\bexample[_-]\w+\b', 
            r'\bsample[_-]\w+\b', r'\bfake[_-]\w+\b'
        ]
        
        self.hardcoded_patterns = [
            r'generated-id', r'test-\d+', r'id-\d+',
            r'"123"', r"'123'", r'return\s*{{}}', r'return\s*\[\]'
        ]
        
        self.not_implemented_patterns = [
            r'not[_\s]implemented', r'raise\s+NotImplementedError',
            r'pass\s*$', r'\.\.\.', r'# Implementation goes here'
        ]
        
    def check_file(self, filepath: Path) -> List[Tuple[int, str, str]]:
        """Check a single file for issues"""
        issues = []
        
        try:
            content = filepath.read_text()
            lines = content.splitlines()
            
            for line_num, line in enumerate(lines, 1):
                # Check for TODOs
                for pattern in self.todo_patterns:
                    if re.search(pattern, line, re.IGNORECASE):
                        issues.append((line_num, "TODO", f"Found TODO marker: {{line.strip()}}"))
                
                # Check for placeholders
                for pattern in self.placeholder_patterns:
                    if re.search(pattern, line, re.IGNORECASE):
                        issues.append((line_num, "PLACEHOLDER", f"Found placeholder: {{line.strip()}}"))
                
                # Check for hardcoded values
                for pattern in self.hardcoded_patterns:
                    if re.search(pattern, line):
                        issues.append((line_num, "HARDCODED", f"Found hardcoded value: {{line.strip()}}"))
                
                # Check for not implemented
                for pattern in self.not_implemented_patterns:
                    if re.search(pattern, line, re.IGNORECASE):
                        issues.append((line_num, "NOT_IMPL", f"Not implemented: {{line.strip()}}"))
                        
        except Exception as e:
            issues.append((0, "ERROR", f"Failed to check file: {{e}}"))
            
        return issues
    
    def check_ast_implementation(self, filepath: Path) -> List[Tuple[int, str, str]]:
        """Use AST to find empty implementations"""
        issues = []
        
        try:
            content = filepath.read_text()
            tree = ast.parse(content)
            
            for node in ast.walk(tree):
                # Check for functions that only return empty dict/list
                if isinstance(node, ast.FunctionDef):
                    if len(node.body) == 1 and isinstance(node.body[0], ast.Return):
                        return_val = node.body[0].value
                        if isinstance(return_val, (ast.Dict, ast.List)) and not return_val.keys:
                            issues.append((
                                node.lineno, 
                                "EMPTY_IMPL", 
                                f"Function '{{node.name}}' returns empty {{{{container}}}}"
                            ))
                            
        except Exception:
            # AST parsing might fail for various reasons, that's OK
            pass
            
        return issues
    
    def check_resources(self) -> List[str]:
        """Check for missing required resources"""
        missing = []
        
        # Check server.py for path references
        server_file = Path("server.py")
        if server_file.exists():
            content = server_file.read_text()
            
            # Look for directory creation patterns
            dir_patterns = [
                r"Path\([\"']([^\"']+)[\"']\)",
                r"mkdir\([\"']([^\"']+)[\"']\)",
                r"\.home\(\)\s*/\s*[\"']([^\"']+)[\"']"
            ]
            
            for pattern in dir_patterns:
                matches = re.findall(pattern, content)
                for match in matches:
                    path = Path(match)
                    if not path.exists() and not any(p in str(path) for p in ['~', '$', '{{']):
                        missing.append(f"Directory not found: {{match}}")
                        
            # Check for environment variables
            env_pattern = r"os\.environ\.get\([\"']([^\"']+)[\"']\)"
            env_matches = re.findall(env_pattern, content)
            for env_var in env_matches:
                if env_var not in os.environ:
                    missing.append(f"Environment variable not set: {{env_var}}")
                    
        return missing
    
    def verify_all(self):
        """Run all verification checks"""
        print("🔍 Implementation Verification for {project_name}")
        print("=" * 70)
        
        # Check server.py
        server_file = Path("server.py")
        if not server_file.exists():
            print("❌ ERROR: server.py not found!")
            return
            
        print("\\nChecking server.py for incomplete implementations...")
        print("-" * 70)
        
        # Regular pattern checks
        issues = self.check_file(server_file)
        
        # AST-based checks
        ast_issues = self.check_ast_implementation(server_file)
        issues.extend(ast_issues)
        
        # Resource checks
        missing_resources = self.check_resources()
        
        # Display results
        if not issues and not missing_resources:
            print("\\n✅ No implementation issues found!")
            print("\\nYour MCP appears to be fully implemented.")
        else:
            if issues:
                print(f"\\n⚠️  Found {{len(issues)}} implementation issue(s):\\n")
                
                # Group by type
                by_type = {{}}
                for line_num, issue_type, description in issues:
                    if issue_type not in by_type:
                        by_type[issue_type] = []
                    by_type[issue_type].append((line_num, description))
                
                for issue_type, items in by_type.items():
                    print(f"\\n{{issue_type}} Issues:")
                    for line_num, desc in items:
                        print(f"  Line {{line_num}}: {{desc}}")
                        
            if missing_resources:
                print(f"\\n⚠️  Missing Resources:\\n")
                for resource in missing_resources:
                    print(f"  - {{resource}}")
                    
            print("\\n" + "=" * 70)
            print("📋 REQUIRED ACTIONS:")
            print("=" * 70)
            
            if "TODO" in by_type or "FIXME" in by_type:
                print("\\n1. Address all TODO/FIXME comments in server.py")
                
            if "PLACEHOLDER" in by_type or "HARDCODED" in by_type:
                print("\\n2. Replace placeholder/mock data with real implementations:")
                print("   - Use actual data storage (files, database, etc.)")
                print("   - Generate real IDs (uuid, timestamp-based, etc.)")
                print("   - Implement actual business logic")
                
            if "NOT_IMPL" in by_type or "EMPTY_IMPL" in by_type:
                print("\\n3. Implement empty function bodies:")
                print("   - Add the core functionality described in docstrings")
                print("   - Handle edge cases and errors properly")
                print("   - Return meaningful data, not empty containers")
                
            if missing_resources:
                print("\\n4. Create missing resources:")
                for resource in missing_resources:
                    if "Directory" in resource:
                        print(f"   - Create directory: {{resource.split(': ')[1]}}")
                    elif "Environment" in resource:
                        print(f"   - Set environment variable: {{resource.split(': ')[1]}}")
                        
            print("\\n5. After fixing, run tests again: python scripts/test.py")
            print("\\n6. Then run this verification again: python scripts/verify.py")
        
        print("\\n" + "=" * 70)
        
        # Return exit code
        if issues or missing_resources:
            sys.exit(1)
        else:
            sys.exit(0)


if __name__ == "__main__":
    import os
    verifier = ImplementationVerifier()
    verifier.verify_all()
'''

# Verification template for scripts directory
VERIFICATION_TEMPLATE_FOR_SCRIPTS = r'''#!/usr/bin/env python3
"""
Implementation Verification for {project_name}
Checks for incomplete implementations and missing requirements

Generated by KEN-MCP
Original Requirements: {requirements}
"""

import os
import re
import sys
import ast
from pathlib import Path
from typing import List, Tuple, Set


class ImplementationVerifier:
    """Verifies that the MCP implementation is complete"""
    
    def __init__(self, project_dir_name: str):
        self.project_dir = Path(__file__).parent.parent / project_dir_name
        self.issues = []
        self.warnings = []
        self.checked_files = []
        
        # Patterns that indicate incomplete implementation
        self.todo_patterns = [
            r'TODO:', r'FIXME:', r'XXX:', r'HACK:', r'NOTE:',
            r'TODO\s*\(', r'FIXME\s*\(', r'XXX\s*\('
        ]
        
        self.placeholder_patterns = [
            r'\bmock\b', r'\bdummy\b', r'\btest[_-]data\b', 
            r'\bplaceholder\b', r'\bexample[_-]\w+\b', 
            r'\bsample[_-]\w+\b', r'\bfake[_-]\w+\b'
        ]
        
        self.hardcoded_patterns = [
            r'generated-id', r'test-\d+', r'id-\d+',
            r'"123"', r"'123'", r'return\s*{{}}', r'return\s*\[\]'
        ]
        
        self.not_implemented_patterns = [
            r'not[_\s]implemented', r'raise\s+NotImplementedError',
            r'pass\s*$', r'\.\.\.', r'# Implementation goes here'
        ]
        
    def check_file(self, filepath: Path) -> List[Tuple[int, str, str]]:
        """Check a single file for issues"""
        issues = []
        
        try:
            content = filepath.read_text()
            lines = content.splitlines()
            
            for line_num, line in enumerate(lines, 1):
                # Check for TODOs
                for pattern in self.todo_patterns:
                    if re.search(pattern, line, re.IGNORECASE):
                        issues.append((line_num, "TODO", f"Found TODO marker: {{line.strip()}}"))
                
                # Check for placeholders
                for pattern in self.placeholder_patterns:
                    if re.search(pattern, line, re.IGNORECASE):
                        issues.append((line_num, "PLACEHOLDER", f"Found placeholder: {{line.strip()}}"))
                
                # Check for hardcoded values
                for pattern in self.hardcoded_patterns:
                    if re.search(pattern, line):
                        issues.append((line_num, "HARDCODED", f"Found hardcoded value: {{line.strip()}}"))
                
                # Check for not implemented
                for pattern in self.not_implemented_patterns:
                    if re.search(pattern, line, re.IGNORECASE):
                        issues.append((line_num, "NOT_IMPL", f"Not implemented: {{line.strip()}}"))
                        
        except Exception as e:
            issues.append((0, "ERROR", f"Failed to check file: {{e}}"))
            
        return issues
    
    def check_ast_implementation(self, filepath: Path) -> List[Tuple[int, str, str]]:
        """Use AST to find empty implementations"""
        issues = []
        
        try:
            content = filepath.read_text()
            tree = ast.parse(content)
            
            for node in ast.walk(tree):
                # Check for functions that only return empty dict/list
                if isinstance(node, ast.FunctionDef):
                    if len(node.body) == 1 and isinstance(node.body[0], ast.Return):
                        return_val = node.body[0].value
                        if isinstance(return_val, (ast.Dict, ast.List)) and not return_val.keys:
                            issues.append((
                                node.lineno, 
                                "EMPTY_IMPL", 
                                f"Function '{{node.name}}' returns empty container"
                            ))
                            
        except Exception:
            # AST parsing might fail for various reasons, that's OK
            pass
            
        return issues
    
    def check_resources(self) -> List[str]:
        """Check for missing required resources"""
        missing = []
        
        # Check server.py for path references
        server_file = self.project_dir / "server.py"
        if server_file.exists():
            content = server_file.read_text()
            
            # Look for directory creation patterns
            dir_patterns = [
                r"Path\([\"']([^\"']+)[\"']\)",
                r"mkdir\([\"']([^\"']+)[\"']\)",
                r"\.home\(\)\s*/\s*[\"']([^\"']+)[\"']"
            ]
            
            for pattern in dir_patterns:
                matches = re.findall(pattern, content)
                for match in matches:
                    path = Path(match)
                    if not path.exists() and not any(p in str(path) for p in ['~', '$', '{{']):
                        missing.append(f"Directory not found: {{match}}")
                        
            # Check for environment variables
            env_pattern = r"os\.environ\.get\([\"']([^\"']+)[\"']\)"
            env_matches = re.findall(env_pattern, content)
            for env_var in env_matches:
                if env_var not in os.environ:
                    missing.append(f"Environment variable not set: {{env_var}}")
                    
        return missing
    
    def verify_all(self):
        """Run all verification checks"""
        print("🔍 Implementation Verification for {project_name}")
        print("=" * 70)
        
        # Check server.py in project directory
        server_file = self.project_dir / "server.py"
        if not server_file.exists():
            print(f"❌ ERROR: server.py not found in {{self.project_dir}}!")
            return
            
        print(f"\\nChecking {{server_file}} for incomplete implementations...")
        print("-" * 70)
        
        # Regular pattern checks
        issues = self.check_file(server_file)
        
        # AST-based checks
        ast_issues = self.check_ast_implementation(server_file)
        issues.extend(ast_issues)
        
        # Resource checks
        missing_resources = self.check_resources()
        
        # Display results
        if not issues and not missing_resources:
            print("\\n✅ No implementation issues found!")
            print("\\nYour MCP appears to be fully implemented.")
        else:
            if issues:
                print(f"\\n⚠️  Found {{len(issues)}} implementation issue(s):\\n")
                
                # Group by type
                by_type = {{}}
                for line_num, issue_type, description in issues:
                    if issue_type not in by_type:
                        by_type[issue_type] = []
                    by_type[issue_type].append((line_num, description))
                
                for issue_type, items in by_type.items():
                    print(f"\\n{{issue_type}} Issues:")
                    for line_num, desc in items:
                        print(f"  Line {{line_num}}: {{desc}}")
                        
            if missing_resources:
                print(f"\\n⚠️  Missing Resources:\\n")
                for resource in missing_resources:
                    print(f"  - {{resource}}")
                    
            print("\\n" + "=" * 70)
            print("📋 REQUIRED ACTIONS:")
            print("=" * 70)
            
            if "TODO" in by_type or "FIXME" in by_type:
                print("\\n1. Address all TODO/FIXME comments in server.py")
                
            if "PLACEHOLDER" in by_type or "HARDCODED" in by_type:
                print("\\n2. Replace placeholder/mock data with real implementations:")
                print("   - Use actual data storage (files, database, etc.)")
                print("   - Generate real IDs (uuid, timestamp-based, etc.)")
                print("   - Implement actual business logic")
                
            if "NOT_IMPL" in by_type or "EMPTY_IMPL" in by_type:
                print("\\n3. Implement empty function bodies:")
                print("   - Add the core functionality described in docstrings")
                print("   - Handle edge cases and errors properly")
                print("   - Return meaningful data, not empty containers")
                
            if missing_resources:
                print("\\n4. Create missing resources:")
                for resource in missing_resources:
                    if "Directory" in resource:
                        print(f"   - Create directory: {{resource.split(': ')[1]}}")
                    elif "Environment" in resource:
                        print(f"   - Set environment variable: {{resource.split(': ')[1]}}")
                        
            print("\\n5. After fixing, run tests again: python scripts/test.py")
            print("\\n6. Then run this verification again: python scripts/verify.py")
        
        print("\\n" + "=" * 70)
        
        # Return exit code
        if issues or missing_resources:
            sys.exit(1)
        else:
            sys.exit(0)


if __name__ == "__main__":
    verifier = ImplementationVerifier("{project_dir_name}")
    verifier.verify_all()
'''

# CLAUDE.md template for project-specific rules and context
CLAUDE_MD_TEMPLATE = r'''# MCP Development Rules & Context for {project_name}

## Project Overview
- **Generated by**: KEN-MCP v{version}  
- **Project Name**: {project_name}
- **Purpose**: {description}
- **Original Requirements**: {requirements}
- **Tools**: {tool_count} tools ({tool_names})
- **Resources**: {resource_count} resources ({resource_names})

## What is MCP (Model Context Protocol)
MCP is a standardized protocol that allows AI models like Claude to interact with external tools and resources through a JSON-RPC interface. Key concepts:

- **Communication**: Bidirectional JSON-RPC 2.0 over stdio (stdin/stdout)
- **Process Model**: Claude Code launches the MCP server as a subprocess
- **Protocol Flow**: Claude sends JSON-RPC requests → MCP server processes → Returns JSON-RPC responses
- **Critical Constraint**: ONLY valid JSON-RPC messages can go to stdout

## What is FastMCP
FastMCP is a Python framework that dramatically simplifies MCP server development:

- **Protocol Handling**: Automatically manages JSON-RPC 2.0 communication
- **Decorators**: Use @mcp.tool and @mcp.resource for easy function registration  
- **Async Support**: Built-in support for async operations
- **Error Handling**: Proper error responses without breaking the protocol
- **Stdio Management**: Handles stdin/stdout correctly when used properly

## CRITICAL RULES (NEVER VIOLATE)

### 1. Stdout Protocol Rules
- **NEVER** use `print()` statements - they corrupt the JSON-RPC stream
- **NEVER** output anything to stdout except through FastMCP
- **NEVER** allow exceptions to reach stdout unhandled
- **ALWAYS** let FastMCP handle all stdout communication

### 2. Logging Rules  
- **ALWAYS** use `logger.info()`, `logger.error()`, `logger.debug()` for output
- **ALL** logging goes to stderr (FastMCP configures this automatically)
- **NEVER** redirect or modify the logging setup in server.py
- **USE** structured logging for debugging: `logger.info("Action completed", extra={{"key": "value"}})`

### 3. Error Handling Rules
- **ALWAYS** catch exceptions in tool functions
- **RETURN** error messages as strings, not raise exceptions
- **VALIDATE** all inputs before processing
- **HANDLE** edge cases gracefully with meaningful error messages

### 4. Implementation Rules
- **REPLACE** all TODO comments with actual implementation
- **REMOVE** all placeholder/mock data (verify.py will catch these)
- **IMPLEMENT** real business logic, not just return empty containers
- **TEST** thoroughly with test.py before considering complete

## Understanding This MCP Server

### Generated Tools
{tools_list}

**Note**: Each tool has detailed implementation requirements in server.py. The above are concise summaries.

### Generated Resources  
{resources_list}

### Architecture
- **Server Entry**: server.py contains the FastMCP server
- **Protocol**: JSON-RPC 2.0 over stdio
- **Logging**: All logs go to stderr via Python logging
- **Testing**: test.py validates functionality
- **Verification**: verify.py checks for incomplete implementations
- **Diagnostics**: diagnose.py troubleshoots connection issues

## Implementation Workflow

### 1. Understand the Requirements
- Read the original requirements: {requirements}
- Identify what each tool should actually do
- Understand the expected inputs and outputs

### 2. Replace Placeholders
- Find all "TODO: Claude, implement..." comments
- Replace mock data with real implementations  
- Remove hardcoded IDs like "generated-id"
- Implement actual business logic

### 3. Test Continuously
```bash
python3 scripts/test.py     # Run functionality tests
python3 scripts/verify.py   # Check for incomplete implementations  
python3 scripts/diagnose.py # Debug connection issues
```

### 4. Validation Patterns
- **Strings**: Check for empty/null, validate format, sanitize input
- **Numbers**: Validate range, check for NaN/infinity
- **Objects**: Verify required fields exist and have correct types
- **Arrays**: Check bounds, validate each element

## Common Implementation Patterns

### Tool Functions
```python
@mcp.tool()
async def my_tool(ctx: Context, param: str) -> str:
    # 1. Validate inputs
    if not param or not isinstance(param, str):
        return "Error: param must be a non-empty string"
    
    # 2. Log the operation (goes to stderr)
    await ctx.info(f"Processing tool request with param: {{param}}")
    
    # 3. Implement business logic
    try:
        result = await some_async_operation(param)
        return result
    except Exception as e:
        # 4. Handle errors gracefully
        await ctx.error(f"Tool failed: {{e}}")
        return f"Error: {{str(e)}}"
```

### Resource Functions
```python
@mcp.resource("scheme://resource-name")
async def my_resource(ctx: Context) -> str:
    try:
        # Implement resource logic
        data = await fetch_resource_data()
        return json.dumps(data)
    except Exception as e:
        await ctx.error(f"Resource failed: {{e}}")
        return json.dumps({{"error": str(e)}})
```

## Platform Considerations

### Command Differences
- **Windows**: Use `py` instead of `python3`
- **macOS/Linux**: Use `python3` 
- **All Platforms**: The shebang line is auto-generated correctly

### Path Handling
```python
from pathlib import Path
# Cross-platform path handling
data_dir = Path.home() / ".mcp_data" / "my_app"
data_dir.mkdir(parents=True, exist_ok=True)
```

## Debugging Guidelines

### Connection Issues
1. **Run Diagnostics**: `python3 scripts/diagnose.py` checks common problems
2. **Check Logs**: Look for stderr output when starting the server
3. **Validate Syntax**: Ensure no Python syntax errors
4. **Test Manually**: Run `python3 server.py` and look for startup errors

### Test Failures
1. **Read Error Messages**: test.py provides detailed failure information
2. **Check Implementation**: Ensure tools return expected data types
3. **Validate Logic**: Verify business logic matches requirements
4. **Fix Incrementally**: Address one test failure at a time

### Verification Issues
1. **Run verify.py**: Identifies TODOs, placeholders, and hardcoded values
2. **Address Each Issue**: Replace placeholders with real implementations
3. **Re-run Verification**: Ensure all issues are resolved
4. **Test Again**: Verify functionality still works after changes

## FastMCP Best Practices

### Async Operations
```python
# Good: Proper async handling
async def process_data(data):
    async with aiohttp.ClientSession() as session:
        response = await session.get(url)
        return await response.json()

# Bad: Blocking operations in async functions
async def bad_process(data):
    time.sleep(5)  # Blocks the event loop
    return data
```

### Error Responses
```python
# Good: Return error strings
@mcp.tool()
async def my_tool(ctx: Context, param: str) -> str:
    if not param:
        return "Error: param is required"
    return f"Processed: {{param}}"

# Bad: Raise exceptions  
@mcp.tool()
async def bad_tool(ctx: Context, param: str) -> str:
    if not param:
        raise ValueError("param is required")  # Breaks protocol
```

## Claude Code Workflow Commands

### MCP Management
```bash
# Add an MCP to Claude Code (Global - recommended)
claude mcp add <name> -s user <command>

# Add an MCP to Claude Code (Local - current directory only)
claude mcp add <name> <command>

# Remove an MCP from Claude Code  
claude mcp remove <name>

# List all configured MCPs and their status
claude mcp list

# Continue a conversation after restart
claude --continue
```

### Critical Workflow Rule
**⚠️ IMPORTANT**: Whenever you make changes to ANY MCP server code:
1. Save your changes
2. **ALWAYS** request a restart: "Please restart Claude Code for these changes to take effect"  
3. After restart, use `claude --continue` to continue the conversation
4. Changes will NOT work until Claude Code is restarted!

This applies to:
- Modifying server.py implementations
- Fixing bugs or adding features
- Any code changes in the MCP directory

### Example MCP Management Workflow
```bash
# 1. Add your MCP (Global - recommended)
claude mcp add my-project -s user "/path/to/project/run_server.py"

# 2. Check it was added
claude mcp list

# 3. Restart Claude Code (changes won't work until restart!)
# Exit and restart Claude Code application

# 4. After restart, verify connection
claude mcp list  # Should show "Active ✓"

# 5. Continue previous conversation if needed
claude --continue
```

## Remember
- You are building a server that Claude communicates with via JSON-RPC
- The protocol is strict - any stdout pollution breaks everything
- FastMCP handles the protocol layer - focus on implementing the business logic
- All generated code has structure but needs real implementation
- Use the verification tools to ensure completeness
- Test thoroughly before considering the implementation complete
- **ALWAYS request restart after MCP changes before expecting them to work!**

## Success Criteria
✅ All tests in test.py pass  
✅ verify.py reports no remaining issues  
✅ diagnose.py shows no connection problems  
✅ MCP connects successfully in Claude Code  
✅ All placeholder code has been replaced with real implementations  
✅ Error cases are handled gracefully  
✅ Logging goes to stderr only
'''

# Generation date format
DATE_FORMAT = '%Y-%m-%d'