import subprocess
import sys
from typing import Any

from atac.runtimes.v1.models import ParsedAction


class BashExecutor:
    """Executes bash:// actions."""
    
    async def execute(self, action: ParsedAction, args: dict[str, Any]) -> Any:
        """
        Execute a bash command.
        
        Args:
            action: Should represent a bash:// scheme.
            args: Needs a 'command' argument.
            
        Returns:
            A dictionary with 'stdout', 'stderr', and 'returncode'.
        """
        if action.scheme != "bash":
            raise ValueError(f"BashExecutor cannot handle scheme: {action.scheme}")
            
        if "command" not in args:
            raise ValueError("BashExecutor requires a 'command' argument.")
            
        command = args["command"]
        
        process = subprocess.run(
            command,
            shell=True,
            capture_output=True,
            text=True
        )
        
        # Print stdout/stderr directly to terminal
        if process.stdout:
            sys.stdout.write(process.stdout)
        if process.stderr:
            sys.stderr.write(process.stderr)
        
        if process.returncode != 0:
             raise RuntimeError(f"Bash command failed with code {process.returncode}:\n{process.stderr}")
             
        return {
            "stdout": process.stdout,
            "stderr": process.stderr,
            "returncode": process.returncode
        }

