"""
Happy Frog - CircuitPython Encoder

This module converts parsed Happy Frog Script commands into CircuitPython code that can
be executed on microcontrollers like the Seeed Xiao RP2040.

Educational Purpose: This demonstrates code generation, microcontroller programming,
and how to translate high-level commands into low-level hardware operations.

Author: ZeroDumb
License: GNU GPLv3
"""

from typing import List, Dict, Any, Optional
from .parser import HappyFrogScript, HappyFrogCommand, CommandType


class EncoderError(Exception):
    """Custom exception for encoding errors."""
    pass


class CircuitPythonEncoder:
    """
    Encoder that converts parsed Happy Frog Script commands into CircuitPython code.
    
    This encoder generates human-readable CircuitPython code that can be directly
    uploaded to compatible microcontrollers. It includes educational comments
    to help users understand how each command works.
    """
    
    def __init__(self):
        """Initialize the encoder with key mappings and templates."""
        # USB HID key codes for CircuitPython
        self.key_codes = {
            # Basic keys
            CommandType.ENTER: "Keycode.ENTER",
            CommandType.SPACE: "Keycode.SPACE",
            CommandType.TAB: "Keycode.TAB",
            CommandType.BACKSPACE: "Keycode.BACKSPACE",
            CommandType.DELETE: "Keycode.DELETE",
            
            # Arrow keys
            CommandType.UP: "Keycode.UP_ARROW",
            CommandType.DOWN: "Keycode.DOWN_ARROW",
            CommandType.LEFT: "Keycode.LEFT_ARROW",
            CommandType.RIGHT: "Keycode.RIGHT_ARROW",
            
            # Navigation keys
            CommandType.HOME: "Keycode.HOME",
            CommandType.END: "Keycode.END",
            CommandType.INSERT: "Keycode.INSERT",
            CommandType.PAGE_UP: "Keycode.PAGE_UP",
            CommandType.PAGE_DOWN: "Keycode.PAGE_DOWN",
            CommandType.ESCAPE: "Keycode.ESCAPE",
            
            # Function keys
            CommandType.F1: "Keycode.F1",
            CommandType.F2: "Keycode.F2",
            CommandType.F3: "Keycode.F3",
            CommandType.F4: "Keycode.F4",
            CommandType.F5: "Keycode.F5",
            CommandType.F6: "Keycode.F6",
            CommandType.F7: "Keycode.F7",
            CommandType.F8: "Keycode.F8",
            CommandType.F9: "Keycode.F9",
            CommandType.F10: "Keycode.F10",
            CommandType.F11: "Keycode.F11",
            CommandType.F12: "Keycode.F12",
            
            # Modifier keys
            CommandType.CTRL: "Keycode.CONTROL",
            CommandType.SHIFT: "Keycode.SHIFT",
            CommandType.ALT: "Keycode.ALT",
            CommandType.MOD: "Keycode.GUI",  # MOD maps to GUI (Windows/Command key)
            
            # Execution control
            CommandType.PAUSE: "PAUSE",  # Special handling for PAUSE command
        }
        
        # CircuitPython code templates
        self.templates = {
            'header': self._get_header_template(),
            'footer': self._get_footer_template(),
            'delay': self._get_delay_template(),
            'string': self._get_string_template(),
            'key_press': self._get_key_press_template(),
            'comment': self._get_comment_template(),
            'repeat': self._get_repeat_template(),
            'conditional': self._get_conditional_template(),
            'loop': self._get_loop_template(),
            'log': self._get_log_template(),
        }
        
        # State for advanced features
        self.default_delay = 0  # Default delay between commands
        self.last_command = None  # For REPEAT functionality
        self.safe_mode = True  # Safe mode enabled by default
    
    def encode(self, script: HappyFrogScript, output_file: Optional[str] = None) -> str:
        """
        Encode a parsed Happy Frog Script into CircuitPython code.
        
        Args:
            script: Parsed HappyFrogScript object
            output_file: Optional output file path
            
        Returns:
            Generated CircuitPython code as string
            
        Raises:
            EncoderError: If encoding fails
        """
        try:
            # Generate the main code
            code_lines = []
            
            # Add header with educational comments
            code_lines.extend(self._generate_header(script))
            
            # Add main execution code
            code_lines.extend(self._generate_main_code(script))
            
            # Add footer
            code_lines.extend(self._generate_footer())
            
            # Join all lines
            code = '\n'.join(code_lines)
            
            # Write to file if specified
            if output_file:
                with open(output_file, 'w', encoding='utf-8') as f:
                    f.write(code)
            
            return code
            
        except Exception as e:
            raise EncoderError(f"Failed to encode script: {str(e)}")
    
    def _generate_header(self, script: HappyFrogScript) -> List[str]:
        """Generate the header section of the CircuitPython code."""
        lines = []
        
        # Add template header (conditional based on safe mode)
        if self.safe_mode:
            lines.extend(self.templates['header'].split('\n'))
        else:
            # Minimal header for production code
            lines.extend([
                '"""',
                'Happy Frog - Generated CircuitPython Code',
                '"""',
                '',
                'import time',
                'import usb_hid',
                'from adafruit_hid.keyboard import Keyboard',
                'from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS',
                'from adafruit_hid.keycode import Keycode',
                '',
                '# Initialize HID devices',
                'keyboard = Keyboard(usb_hid.devices)',
                'keyboard_layout = KeyboardLayoutUS(keyboard)',
                ''
            ])
        
        # Add script metadata as comments (only in safe mode)
        if self.safe_mode:
            lines.append("")
            lines.append("# Script Information:")
            lines.append(f"# Source: {script.metadata.get('source', 'Unknown')}")
            lines.append(f"# Total Commands: {script.metadata.get('total_commands', 0)}")
            lines.append(f"# Total Lines: {script.metadata.get('total_lines', 0)}")
            lines.append("")
        
        return lines
    
    def _generate_main_code(self, script: HappyFrogScript) -> List[str]:
        """Generate the main execution code from script commands."""
        lines = []
        
        if self.safe_mode:
            lines.append("# Main execution loop")
        lines.append("def main():")
        if self.safe_mode:
            lines.append("    # Wait for system to recognize the device")
        lines.append("    time.sleep(2)")
        lines.append("")
        
        # Process each command
        for i, command in enumerate(script.commands):
            lines.extend(self._encode_command(command, i + 1))
        
        lines.append("")
        if self.safe_mode:
            lines.append("# Run the main function")
        lines.append("if __name__ == '__main__':")
        lines.append("    main()")
        lines.append("")
        
        return lines
    
    def _encode_command(self, command: HappyFrogCommand, command_index: int) -> List[str]:
        """Encode a single command into CircuitPython code."""
        lines = []
        
        # Add comment with original command (only in safe mode)
        if self.safe_mode:
            comment = f"    # Command {command_index}: {command.raw_text}"
            lines.append(comment)
        
        # Encode based on command type
        if command.command_type == CommandType.DELAY:
            lines.extend(self._encode_delay(command))
        elif command.command_type == CommandType.STRING:
            lines.extend(self._encode_string(command))
        elif command.command_type == CommandType.MODIFIER_COMBO:
            lines.extend(self._encode_modifier_combo(command))
        elif command.command_type == CommandType.PAUSE:
            lines.extend(self._encode_pause(command))
        elif command.command_type == CommandType.REPEAT:
            lines.extend(self._encode_repeat(command))
        elif command.command_type in [CommandType.DEFAULT_DELAY, CommandType.DEFAULTDELAY]:
            lines.extend(self._encode_default_delay(command))
        elif command.command_type == CommandType.IF:
            lines.extend(self._encode_if(command))
        elif command.command_type == CommandType.ELSE:
            lines.extend(self._encode_else(command))
        elif command.command_type == CommandType.ENDIF:
            lines.extend(self._encode_endif(command))
        elif command.command_type == CommandType.WHILE:
            lines.extend(self._encode_while(command))
        elif command.command_type == CommandType.ENDWHILE:
            lines.extend(self._encode_endwhile(command))
        elif command.command_type == CommandType.RANDOM_DELAY:
            lines.extend(self._encode_random_delay(command))
        elif command.command_type == CommandType.LOG:
            lines.extend(self._encode_log(command))
        elif command.command_type == CommandType.VALIDATE:
            lines.extend(self._encode_validate(command))
        elif command.command_type == CommandType.SAFE_MODE:
            lines.extend(self._encode_safe_mode(command))
        elif command.command_type == CommandType.ATTACKMODE:
            lines.extend(self._encode_attackmode(command))
        elif command.command_type in self.key_codes:
            lines.extend(self._encode_key_press(command))
        elif command.command_type in [CommandType.COMMENT, CommandType.REM]:
            lines.extend(self._encode_comment(command))
        else:
            # Unknown command - add warning comment (only in safe mode)
            if self.safe_mode:
                lines.append(f"    # WARNING: Unknown command '{command.command_type}'")
            lines.append("    pass")
        
        lines.append("")  # Add blank line for readability
        return lines
    
    def _encode_delay(self, command: HappyFrogCommand) -> List[str]:
        """Encode a DELAY command."""
        try:
            delay_ms = int(command.parameters[0])
            if delay_ms < 0:
                raise EncoderError("Delay value must be non-negative")
            
            if self.safe_mode:
                return [
                    f"    time.sleep({delay_ms / 1000.0})  # Delay for {delay_ms}ms"
                ]
            else:
                return [
                    f"    time.sleep({delay_ms / 1000.0})"
                ]
        except (ValueError, IndexError):
            raise EncoderError(f"Invalid delay value '{command.parameters[0] if command.parameters else 'None'}' in command: {command.raw_text}")
    
    def _encode_string(self, command: HappyFrogCommand) -> List[str]:
        """Encode a STRING command."""
        if not command.parameters:
            raise EncoderError(f"STRING command missing text: {command.raw_text}")
        
        text = command.parameters[0]
        # Escape quotes and special characters
        escaped_text = text.replace('\\', '\\\\').replace('"', '\\"')
        
        if self.safe_mode:
            return [
                f'    keyboard_layout.write("{escaped_text}")  # Type: {text}'
            ]
        else:
            return [
                f'    keyboard_layout.write("{escaped_text}")'
            ]
    
    def _encode_pause(self, command: HappyFrogCommand) -> List[str]:
        """Encode a PAUSE command - wait for user input."""
        if self.safe_mode:
            return [
                "    # PAUSE: Waiting for user input (press any key to continue)",
                "    # Note: In CircuitPython, we'll use a long delay as a simple pause",
                "    # For more sophisticated pause functionality, consider using button input",
                "    time.sleep(5)  # Pause for 5 seconds (Ducky Script PAUSE equivalent)"
            ]
        else:
            return [
                "    time.sleep(5)"
            ]
    
    def _encode_modifier_combo(self, command: HappyFrogCommand) -> List[str]:
        """Encode a MODIFIER_COMBO command (e.g., MOD r, CTRL ALT DEL)."""
        if not command.parameters:
            raise EncoderError(f"MODIFIER_COMBO command missing parameters: {command.raw_text}")
        
        lines = []
        
        # Press all keys in the combo
        for param in command.parameters:
            if param.upper() in ['MOD', 'CTRL', 'SHIFT', 'ALT']:
                # It's a modifier key
                key_code = self.key_codes.get(CommandType(param.upper()))
                if key_code:
                    if self.safe_mode:
                        lines.append(f"    keyboard.press({key_code})  # Press {param}")
                    else:
                        lines.append(f"    keyboard.press({key_code})")
            else:
                # It's a regular key - map it to the appropriate keycode
                key_code = self._map_key_to_keycode(param)
                if key_code:
                    if self.safe_mode:
                        lines.append(f"    keyboard.press({key_code})  # Press {param}")
                    else:
                        lines.append(f"    keyboard.press({key_code})")
        
        # Release all keys in reverse order
        for param in reversed(command.parameters):
            if param.upper() in ['MOD', 'CTRL', 'SHIFT', 'ALT']:
                key_code = self.key_codes.get(CommandType(param.upper()))
                if key_code:
                    if self.safe_mode:
                        lines.append(f"    keyboard.release({key_code})  # Release {param}")
                    else:
                        lines.append(f"    keyboard.release({key_code})")
            else:
                key_code = self._map_key_to_keycode(param)
                if key_code:
                    if self.safe_mode:
                        lines.append(f"    keyboard.release({key_code})  # Release {param}")
                    else:
                        lines.append(f"    keyboard.release({key_code})")
        
        return lines
    
    def _map_key_to_keycode(self, key: str) -> str:
        """Map a key string to its CircuitPython keycode."""
        key = key.upper()
        
        # Single letter keys
        if len(key) == 1 and key.isalpha():
            return f"Keycode.{key}"
        
        # Number keys
        if key.isdigit():
            return f"Keycode.{key}"
        
        # Special mappings
        key_mappings = {
            'R': 'Keycode.R',
            'DEL': 'Keycode.DELETE',
            'BACKSPACE': 'Keycode.BACKSPACE',
            'ENTER': 'Keycode.ENTER',
            'SPACE': 'Keycode.SPACE',
            'TAB': 'Keycode.TAB',
            'ESC': 'Keycode.ESCAPE',
            'ESCAPE': 'Keycode.ESCAPE',
        }
        
        return key_mappings.get(key, f"Keycode.{key}")
    
    def _encode_key_press(self, command: HappyFrogCommand) -> List[str]:
        """Encode a key press command."""
        key_code = self.key_codes.get(command.command_type)
        if not key_code:
            raise EncoderError(f"Unsupported key: {command.command_type}")
        
        if self.safe_mode:
            return [
                f"    keyboard.press({key_code})  # Press {command.command_type.value}",
                f"    keyboard.release({key_code})  # Release {command.command_type.value}"
            ]
        else:
            return [
                f"    keyboard.press({key_code})",
                f"    keyboard.release({key_code})"
            ]
    
    def _encode_comment(self, command: HappyFrogCommand) -> List[str]:
        """Encode a comment command."""
        comment_text = command.parameters[0] if command.parameters else ""
        return [
            f"    # {comment_text}"
        ]
    
    def _generate_footer(self) -> List[str]:
        """Generate the footer section of the CircuitPython code."""
        if self.safe_mode:
            return self.templates['footer'].split('\n')
        else:
            return ['"""', 'End of Happy Frog Generated Code', '"""']
    
    def _get_header_template(self) -> str:
        """Get the header template for CircuitPython code."""
        if self.safe_mode:
            return '''"""
Happy Frog - Generated CircuitPython Code
Educational HID Emulation Script

This code was automatically generated from a Happy Frog Script.
It demonstrates how to use CircuitPython for HID emulation.

⚠️ IMPORTANT: Use only for educational purposes and authorized testing!
"""

import time
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

# Initialize HID devices
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)

# Educational note: This creates a virtual keyboard that the computer
# will recognize as a USB HID device. The keyboard can send keystrokes
# just like a physical keyboard would.'''
        else:
            return '''"""
Happy Frog - Generated CircuitPython Code
"""

import time
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

# Initialize HID devices
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)'''
    
    def _get_footer_template(self) -> str:
        """Get the footer template for CircuitPython code."""
        return '''"""
End of Happy Frog Generated Code

Educational Notes:
- This script demonstrates basic HID emulation techniques
- Always test in controlled environments
- Use responsibly and ethically
- Consider the security implications of automated input

For more information, visit: https://github.com/ZeroDumb/happy-frog
"""'''
    
    def _get_delay_template(self) -> str:
        """Get the delay command template."""
        return "time.sleep({delay})  # Delay for {delay_ms}ms"
    
    def _get_string_template(self) -> str:
        """Get the string command template."""
        return 'keyboard_layout.write("{text}")  # Type: {original_text}'
    
    def _get_key_press_template(self) -> str:
        """Get the key press template."""
        return [
            "keyboard.press({key_code})  # Press {key_name}",
            "keyboard.release({key_code})  # Release {key_name}"
        ]
    
    def _get_comment_template(self) -> str:
        """Get the comment template."""
        return "# {comment_text}"
    
    def _get_repeat_template(self) -> str:
        """Get the repeat command template."""
        return "    # REPEAT: Repeat the last command"
    
    def _get_conditional_template(self) -> str:
        """Get the conditional command template."""
        return "    # CONDITIONAL: Execute command based on condition"
    
    def _get_loop_template(self) -> str:
        """Get the loop command template."""
        return "    # LOOP: Repeat command multiple times"
    
    def _get_log_template(self) -> str:
        """Get the log command template."""
        return "    # LOG: Record command execution"
    
    def validate_script(self, script: HappyFrogScript) -> List[str]:
        """
        Validate a script for encoding compatibility.
        
        Args:
            script: Parsed HappyFrogScript object
            
        Returns:
            List of warning messages (empty if no issues)
        """
        warnings = []
        
        for command in script.commands:
            # Check for unsupported commands
            if command.command_type not in self.key_codes and \
               command.command_type not in [CommandType.DELAY, CommandType.STRING, 
                                           CommandType.COMMENT, CommandType.REM,
                                           CommandType.MODIFIER_COMBO]:
                warnings.append(
                    f"Line {command.line_number}: Command '{command.command_type.value}' "
                    "may not be fully supported"
                )
            
            # Check for very long strings that might cause issues
            if command.command_type == CommandType.STRING and command.parameters:
                text = command.parameters[0]
                if len(text) > 1000:
                    warnings.append(
                        f"Line {command.line_number}: Very long string ({len(text)} chars) "
                        "may cause timing issues"
                    )
        
        return warnings
    
    def _encode_repeat(self, command: HappyFrogCommand) -> List[str]:
        """Encode a REPEAT command - repeat the last command n times."""
        if not command.parameters:
            raise EncoderError(f"REPEAT command missing count: {command.raw_text}")
        
        try:
            repeat_count = int(command.parameters[0])
            if repeat_count < 1:
                raise EncoderError("Repeat count must be at least 1")
            
            if not self.last_command:
                raise EncoderError("No previous command to repeat")
            
            lines = [
                f"    # REPEAT: Repeating last command {repeat_count} times",
                f"    for _ in range({repeat_count}):"
            ]
            
            # Add the last command with proper indentation
            last_lines = self._encode_command(self.last_command, 0)  # 0 for no line number
            for line in last_lines:
                if line.strip() and not line.strip().startswith('#'):
                    lines.append(f"        {line.strip()}")
            
            return lines
            
        except ValueError:
            raise EncoderError(f"Invalid repeat count '{command.parameters[0]}' in command: {command.raw_text}")
    
    def _encode_default_delay(self, command: HappyFrogCommand) -> List[str]:
        """Encode a DEFAULT_DELAY command - set default delay between commands."""
        if not command.parameters:
            raise EncoderError(f"DEFAULT_DELAY command missing value: {command.raw_text}")
        
        try:
            delay_ms = int(command.parameters[0])
            if delay_ms < 0:
                raise EncoderError("Default delay value must be non-negative")
            
            self.default_delay = delay_ms
            return [
                f"    # DEFAULT_DELAY: Set default delay to {delay_ms}ms between commands",
                f"    default_delay = {delay_ms / 1000.0}  # Convert to seconds"
            ]
            
        except ValueError:
            raise EncoderError(f"Invalid default delay value '{command.parameters[0]}' in command: {command.raw_text}")
    
    def _encode_if(self, command: HappyFrogCommand) -> List[str]:
        """Encode an IF command - conditional execution."""
        if not command.parameters:
            raise EncoderError(f"IF command missing condition: {command.raw_text}")
        
        condition = command.parameters[0]
        return [
            f"    # IF: Conditional execution based on '{condition}'",
            f"    # Note: This is a simplified condition check",
            f"    if True:  # Placeholder for condition: {condition}"
        ]
    
    def _encode_else(self, command: HappyFrogCommand) -> List[str]:
        """Encode an ELSE command."""
        return [
            "    # ELSE: Alternative execution path",
            "    else:"
        ]
    
    def _encode_endif(self, command: HappyFrogCommand) -> List[str]:
        """Encode an ENDIF command."""
        return [
            "    # ENDIF: End conditional block"
        ]
    
    def _encode_while(self, command: HappyFrogCommand) -> List[str]:
        """Encode a WHILE command - loop execution."""
        if not command.parameters:
            raise EncoderError(f"WHILE command missing condition: {command.raw_text}")
        
        condition = command.parameters[0]
        return [
            f"    # WHILE: Loop execution based on '{condition}'",
            f"    # Note: This is a simplified loop condition",
            f"    while True:  # Placeholder for condition: {condition}"
        ]
    
    def _encode_endwhile(self, command: HappyFrogCommand) -> List[str]:
        """Encode an ENDWHILE command."""
        return [
            "    # ENDWHILE: End loop block"
        ]
    
    def _encode_random_delay(self, command: HappyFrogCommand) -> List[str]:
        """Encode a RANDOM_DELAY command - random delay for human-like behavior."""
        if len(command.parameters) < 2:
            raise EncoderError(f"RANDOM_DELAY command missing min/max values: {command.raw_text}")
        
        try:
            min_delay = int(command.parameters[0])
            max_delay = int(command.parameters[1])
            if min_delay < 0 or max_delay < min_delay:
                raise EncoderError("Invalid random delay range")
            
            return [
                f"    # RANDOM_DELAY: Human-like random delay between {min_delay}ms and {max_delay}ms",
                f"    import random",
                f"    random_delay = random.uniform({min_delay / 1000.0}, {max_delay / 1000.0})",
                f"    time.sleep(random_delay)"
            ]
            
        except ValueError:
            raise EncoderError(f"Invalid random delay values in command: {command.raw_text}")
    
    def _encode_log(self, command: HappyFrogCommand) -> List[str]:
        """Encode a LOG command - logging for debugging."""
        if not command.parameters:
            raise EncoderError(f"LOG command missing message: {command.raw_text}")
        
        message = command.parameters[0]
        return [
            f"    # LOG: {message}",
            f"    print('Happy Frog Log: {message}')"
        ]
    
    def _encode_validate(self, command: HappyFrogCommand) -> List[str]:
        """Encode a VALIDATE command - validate environment before execution."""
        if not command.parameters:
            raise EncoderError(f"VALIDATE command missing condition: {command.raw_text}")
        
        condition = command.parameters[0]
        return [
            f"    # VALIDATE: Check environment condition '{condition}'",
            f"    # Note: This is a placeholder for environment validation",
            f"    print('Validating: {condition}')"
        ]
    
    def _encode_safe_mode(self, command: HappyFrogCommand) -> List[str]:
        """Encode a SAFE_MODE command - enable/disable safe mode restrictions."""
        if not command.parameters:
            raise EncoderError(f"SAFE_MODE command missing ON/OFF value: {command.raw_text}")
        
        mode = command.parameters[0].upper()
        if mode not in ['ON', 'OFF']:
            raise EncoderError("SAFE_MODE must be ON or OFF")
        
        self.safe_mode = (mode == 'ON')
        return [
            f"    # SAFE_MODE: {'Enabled' if self.safe_mode else 'Disabled'} safe mode restrictions",
            f"    safe_mode = {str(self.safe_mode).lower()}"
        ]
    
    def _encode_attackmode(self, command: HappyFrogCommand) -> List[str]:
        """Encode an ATTACKMODE command - BadUSB attack mode configuration."""
        if not command.parameters:
            raise EncoderError(f"ATTACKMODE command missing configuration: {command.raw_text}")
        
        mode_config = command.parameters[0].upper()
        
        # Handle different ATTACKMODE configurations
        if 'HID' in mode_config:
            return [
                f"    # ATTACKMODE: Configured for HID emulation ({mode_config})",
                f"    # Note: This device is configured as a HID keyboard/mouse",
                f"    # Configuration: {mode_config}"
            ]
        elif 'STORAGE' in mode_config:
            return [
                f"    # ATTACKMODE: Configured for storage emulation ({mode_config})",
                f"    # Note: This device is configured as a storage device",
                f"    # Configuration: {mode_config}"
            ]
        elif mode_config in ['ON', 'OFF']:
            # Legacy ON/OFF support
            self.safe_mode = (mode_config == 'ON')
            return [
                f"    # ATTACKMODE: {'Enabled' if self.safe_mode else 'Disabled'} attack mode",
                f"    safe_mode = {str(self.safe_mode).lower()}"
            ]
        else:
            # Generic ATTACKMODE configuration
            return [
                f"    # ATTACKMODE: Configured with '{mode_config}'",
                f"    # Note: This is a BadUSB attack mode configuration",
                f"    # Configuration: {mode_config}"
            ] 