#!/usr/bin/env python3
"""
Auto-generation script for updating REPL components when language features change.

This script analyzes the lexer and parser to automatically update:
- REPL keyword completion
- Help documentation
- Syntax highlighting hints

Run this after making changes to the language grammar.
"""

import os
import sys
import re
from pathlib import Path
from typing import List, Set, Dict

# Add the src directory to Python path
sys.path.insert(0, str(Path(__file__).parent.parent / 'src'))

from alloy.lexer import AlloyLexer
from alloy.parser import AlloyParser


class REPLUpdater:
    """Updates REPL components based on current language definition"""
    
    def __init__(self):
        self.lexer = AlloyLexer()
        self.parser = AlloyParser()
        self.project_root = Path(__file__).parent.parent
        
    def extract_keywords(self) -> Set[str]:
        """Extract keywords from the lexer"""
        keywords = set()
        
        # Get reserved words from lexer
        if hasattr(self.lexer, 'reserved'):
            keywords.update(self.lexer.reserved.keys())
        
        # Extract from token definitions
        lexer_file = self.project_root / 'src' / 'alloy' / 'lexer.py'
        with open(lexer_file, 'r') as f:
            content = f.read()
        
        # Find token definitions like t_KEYWORD = r'keyword'
        token_pattern = r"t_([A-Z_]+)\s*=\s*r['\"]([^'\"]+)['\"]"
        for match in re.finditer(token_pattern, content):
            token_name, token_value = match.groups()
            if token_name not in ['NUMBER', 'STRING', 'IDENTIFIER'] and token_value.isalpha():
                keywords.add(token_value.lower())
        
        return keywords
    
    def extract_builtin_functions(self) -> Set[str]:
        """Extract built-in functions from parser and interpreter"""
        builtins = set()
        
        # Common built-ins that might be referenced
        builtins.update(['print', 'len', 'type', 'str', 'int', 'float', 'bool'])
        
        return builtins
    
    def extract_grammar_patterns(self) -> Dict[str, List[str]]:
        """Extract grammar patterns for syntax help"""
        patterns = {
            'tool_definition': ['tool <name> takes <params> returns <var> { ... }'],
            'agent_definition': ['agent <name> "<model>" with tools <tools> { ... }'],
            'assignment': ['<var> = <expression>'],
            'tuple_assignment': ['<var1>, <var2> = <expression>'],
            'control_flow': [
                'when <condition> then <action> otherwise <fallback>',
                'for <var> in <iterable> do { ... }',
                'while <condition> do { ... }'
            ],
            'agent_commands': ['<result>, <error> = <agent> <Command> <data>'],
            'chaining': ['<result> = <operation1> then <operation2>']
        }
        
        return patterns
    
    def update_repl_completion(self):
        """Update REPL tab completion"""
        keywords = self.extract_keywords()
        builtins = self.extract_builtin_functions()
        
        completion_code = f'''"""
Auto-generated completion data for Alloy REPL
Generated by scripts/update_repl.py
"""

KEYWORDS = {sorted(list(keywords))}

BUILTIN_FUNCTIONS = {sorted(list(builtins))}

COMMAND_PATTERNS = [
    "tool <name> takes <params> returns <var> {{ ... }}",
    "agent <name> \\"<model>\\" with tools <tools> {{ ... }}",
    "<var> = <expression>",
    "<var1>, <var2> = <expression>",
    "when <condition> then <action> otherwise <fallback>",
    "for <var> in <iterable> do {{ ... }}",
    "while <condition> do {{ ... }}",
    "<result>, <error> = <agent> <Command> <data>",
    "<result> = <operation1> then <operation2>"
]
'''
        
        completion_file = self.project_root / 'src' / 'alloy' / 'completion.py'
        with open(completion_file, 'w') as f:
            f.write(completion_code)
        
        print(f"Updated completion data: {completion_file}")
    
    def update_help_documentation(self):
        """Update help documentation in REPL"""
        patterns = self.extract_grammar_patterns()
        keywords = self.extract_keywords()
        
        help_content = '''
Alloy REPL Commands:
  help          - Show this help message
  exit, quit    - Exit the REPL
  clear         - Clear the screen
  load <file>   - Load and execute an .ay file
  debug on/off  - Toggle debug mode
  env           - Show current environment (variables, tools, agents)
  reset         - Reset the interpreter environment

Language Keywords:
  ''' + ', '.join(sorted(keywords)) + '''

Syntax Patterns:
'''
        
        for category, pattern_list in patterns.items():
            help_content += f"  {category.replace('_', ' ').title()}:\n"
            for pattern in pattern_list:
                help_content += f"    {pattern}\n"
        
        help_content += '''
For multiline input, press Enter on an empty line to execute.
        '''
        
        # Update the REPL file
        repl_file = self.project_root / 'src' / 'alloy' / 'repl.py'
        with open(repl_file, 'r') as f:
            content = f.read()
        
        # Replace the help content
        start_marker = 'print("""'
        end_marker = '""")'
        
        start_idx = content.find(start_marker, content.find('def _print_help'))
        if start_idx != -1:
            end_idx = content.find(end_marker, start_idx)
            if end_idx != -1:
                new_content = (content[:start_idx + len(start_marker)] + 
                             help_content + 
                             content[end_idx:])
                
                with open(repl_file, 'w') as f:
                    f.write(new_content)
                
                print(f"Updated help documentation: {repl_file}")
    
    def update_version_info(self):
        """Update version information"""
        # Read version from pyproject.toml
        pyproject_file = self.project_root / 'pyproject.toml'
        version = "0.1.0"  # default
        
        if pyproject_file.exists():
            with open(pyproject_file, 'r') as f:
                content = f.read()
                version_match = re.search(r'version\s*=\s*"([^"]+)"', content)
                if version_match:
                    version = version_match.group(1)
        
        # Update CLI version
        cli_file = self.project_root / 'src' / 'alloy' / 'cli.py'
        with open(cli_file, 'r') as f:
            content = f.read()
        
        content = re.sub(
            r'version="[^"]*"',
            f'version="%(prog)s {version}"',
            content
        )
        
        with open(cli_file, 'w') as f:
            f.write(content)
        
        print(f"Updated version to {version}")
    
    def run(self):
        """Run all updates"""
        print("Updating REPL components based on current language definition...")
        
        try:
            self.update_repl_completion()
            self.update_help_documentation()
            self.update_version_info()
            print("✅ REPL update completed successfully!")
        except Exception as e:
            print(f"❌ Error updating REPL: {e}")
            sys.exit(1)


if __name__ == "__main__":
    updater = REPLUpdater()
    updater.run()