#!/usr/bin/env python3
"""
Auto-Documentation Hook
Updates documentation when code changes: API specs, README, comments
"""
import subprocess
import json
import sys
import os
import re
from datetime import datetime

def run_command(cmd):
    """Run shell command and return output"""
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        return result.stdout.strip(), result.stderr.strip(), result.returncode
    except Exception as e:
        return "", str(e), 1

def get_file_from_stdin():
    """Get file path from Claude tool input"""
    try:
        # Read from stdin if available
        if not sys.stdin.isatty():
            input_data = json.load(sys.stdin)
            if "tool_input" in input_data:
                tool_input = input_data["tool_input"]
                if "path" in tool_input:
                    return tool_input["path"]
                elif "file_path" in tool_input:
                    return tool_input["file_path"]
        
        # Fallback: get from environment variable
        return os.environ.get("CLAUDE_TOOL_INPUT_FILE_PATH")
    except:
        return None

def is_api_file(file_path):
    """Check if file contains API endpoints"""
    if not file_path or not os.path.exists(file_path):
        return False
    
    api_patterns = [
        r'@app\.route\(',  # Flask
        r'app\.(get|post|put|delete|patch)\(',  # Express
        r'router\.(get|post|put|delete|patch)\(',  # Express Router
        r'@(Get|Post|Put|Delete|Patch)\(',  # NestJS/Spring
        r'func.*http\.Handler',  # Go HTTP
        r'#\[actix_web::(get|post|put|delete|patch)\]',  # Actix Web (Rust)
    ]
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
            return any(re.search(pattern, content, re.IGNORECASE) for pattern in api_patterns)
    except:
        return False

def is_component_file(file_path):
    """Check if file is a UI component"""
    if not file_path:
        return False
    
    # Check file extension and naming patterns
    component_patterns = [
        r'\.component\.(js|ts|jsx|tsx)$',
        r'components/.*\.(js|ts|jsx|tsx)$',
        r'\.vue$',
        r'\.svelte$'
    ]
    
    return any(re.search(pattern, file_path, re.IGNORECASE) for pattern in component_patterns)

def extract_api_endpoints(file_path):
    """Extract API endpoints from file"""
    endpoints = []
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
            lines = content.split('\n')
            
            for i, line in enumerate(lines):
                # Flask routes
                flask_match = re.search(r'@app\.route\([\'"]([^\'"]+)[\'"].*methods=\[([^\]]+)\]', line)
                if flask_match:
                    path = flask_match.group(1)
                    methods = flask_match.group(2).replace("'", "").replace('"', "")
                    endpoints.append(f"{methods} {path}")
                
                # Express routes
                express_match = re.search(r'app\.(get|post|put|delete|patch)\([\'"]([^\'"]+)[\'"]', line)
                if express_match:
                    method = express_match.group(1).upper()
                    path = express_match.group(2)
                    endpoints.append(f"{method} {path}")
                
                # Router routes
                router_match = re.search(r'router\.(get|post|put|delete|patch)\([\'"]([^\'"]+)[\'"]', line)
                if router_match:
                    method = router_match.group(1).upper()
                    path = router_match.group(2)
                    endpoints.append(f"{method} {path}")
    except:
        pass
    
    return endpoints

def update_api_documentation(file_path):
    """Update API documentation"""
    results = []
    
    endpoints = extract_api_endpoints(file_path)
    if not endpoints:
        return results
    
    # Update OpenAPI spec if exists
    openapi_files = ["openapi.yaml", "openapi.yml", "swagger.yaml", "swagger.yml", "api-spec.yaml"]
    for spec_file in openapi_files:
        if os.path.exists(spec_file):
            results.append(f"📝 Found API spec: {spec_file} (manual update needed)")
            break
    
    # Update API documentation file
    api_doc_file = "API.md"
    if os.path.exists(api_doc_file):
        try:
            with open(api_doc_file, 'r') as f:
                content = f.read()
            
            # Add new endpoints section if not exists
            if "## Endpoints" not in content:
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                new_section = f"\n\n## Endpoints\n\n*Last updated: {timestamp}*\n\n"
                for endpoint in endpoints:
                    new_section += f"- `{endpoint}`\n"
                
                with open(api_doc_file, 'a') as f:
                    f.write(new_section)
                
                results.append(f"📝 Updated {api_doc_file} with {len(endpoints)} endpoints")
        except:
            pass
    else:
        # Create new API documentation
        try:
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            with open(api_doc_file, 'w') as f:
                f.write(f"# API Documentation\n\n*Generated: {timestamp}*\n\n## Endpoints\n\n")
                for endpoint in endpoints:
                    f.write(f"- `{endpoint}`\n")
            
            results.append(f"📝 Created {api_doc_file} with {len(endpoints)} endpoints")
        except:
            pass
    
    return results

def update_component_documentation(file_path):
    """Update component documentation"""
    results = []
    
    if not is_component_file(file_path):
        return results
    
    component_name = os.path.splitext(os.path.basename(file_path))[0]
    
    # Check for Storybook
    storybook_patterns = [".storybook", "stories", "*.stories.js", "*.stories.ts"]
    has_storybook = any(os.path.exists(pattern) or len(glob.glob(pattern)) > 0 for pattern in storybook_patterns)
    
    if has_storybook:
        results.append(f"📚 Component {component_name} - Storybook available (manual story update recommended)")
    
    # Update component README if exists
    component_dir = os.path.dirname(file_path)
    readme_file = os.path.join(component_dir, "README.md")
    
    if os.path.exists(readme_file):
        results.append(f"📝 Component README exists: {readme_file}")
    
    return results

def add_function_comments(file_path):
    """Add JSDoc/docstring comments to functions"""
    results = []
    
    if not file_path or not os.path.exists(file_path):
        return results
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # Count functions without comments
        function_patterns = [
            r'function\s+(\w+)\s*\(',  # JavaScript functions
            r'const\s+(\w+)\s*=\s*\(',  # Arrow functions
            r'def\s+(\w+)\s*\(',  # Python functions
            r'func\s+(\w+)\s*\(',  # Go functions
        ]
        
        functions_found = 0
        for pattern in function_patterns:
            matches = re.findall(pattern, content)
            functions_found += len(matches)
        
        if functions_found > 0:
            results.append(f"📋 Found {functions_found} functions in {os.path.basename(file_path)} (consider adding documentation)")
    except:
        pass
    
    return results

def update_readme():
    """Update README.md with project info"""
    results = []
    
    if not os.path.exists("README.md"):
        return results
    
    try:
        with open("README.md", 'r') as f:
            content = f.read()
        
        # Check if README needs updates
        needs_update = False
        
        # Check for outdated "Last updated" timestamp
        last_updated_match = re.search(r'Last updated:?\s*([^\n]+)', content, re.IGNORECASE)
        if last_updated_match:
            # Update timestamp
            current_time = datetime.now().strftime("%Y-%m-%d")
            new_content = re.sub(
                r'Last updated:?\s*[^\n]+',
                f'Last updated: {current_time}',
                content,
                flags=re.IGNORECASE
            )
            
            if new_content != content:
                with open("README.md", 'w') as f:
                    f.write(new_content)
                results.append("📝 Updated README.md timestamp")
        
        # Check for missing sections
        missing_sections = []
        required_sections = ["Installation", "Usage", "API", "Contributing"]
        
        for section in required_sections:
            if f"## {section}" not in content and f"# {section}" not in content:
                missing_sections.append(section)
        
        if missing_sections:
            results.append(f"📝 README.md missing sections: {', '.join(missing_sections)}")
    
    except:
        pass
    
    return results

def generate_changelog_entry(file_path):
    """Generate changelog entry for significant changes"""
    results = []
    
    if not os.path.exists("CHANGELOG.md"):
        return results
    
    # Get recent git commits for this file
    stdout, _, code = run_command(f"git log --oneline -3 -- {file_path} 2>/dev/null")
    if code == 0 and stdout:
        commits = stdout.strip().split('\n')
        if commits and commits[0]:
            latest_commit = commits[0]
            results.append(f"📝 Latest change to {os.path.basename(file_path)}: {latest_commit}")
    
    return results

def main():
    try:
        file_path = get_file_from_stdin()
        
        if not file_path:
            sys.exit(0)  # No file to process
        
        results = []
        
        # API documentation
        if is_api_file(file_path):
            results.extend(update_api_documentation(file_path))
        
        # Component documentation
        if is_component_file(file_path):
            results.extend(update_component_documentation(file_path))
        
        # Function comments
        results.extend(add_function_comments(file_path))
        
        # README updates
        results.extend(update_readme())
        
        # Changelog
        results.extend(generate_changelog_entry(file_path))
        
        # Output results
        if results:
            print("📚 AUTO-DOCUMENTATION UPDATES:")
            for result in results:
                print(f"  {result}")
        
    except Exception as e:
        print(f"❌ Auto-documentation error: {e}")
        sys.exit(0)  # Don't block Claude

if __name__ == "__main__":
    main()