"""Skill script execution tool - executes scripts from skills"""

import os
from typing import Optional
from agents import function_tool

from diona.project.agent.globals import get_skill
from diona.project.shell import ShellCommander, ShellConfig


def _get_unrestricted_shell(cwd: str = None) -> ShellCommander:
    """Get a shell commander with no restrictions
    
    Args:
        cwd: Working directory
        
    Returns:
        ShellCommander instance with empty blacklist
    """
    home_dir = os.path.expanduser("~")
    diona_dir = os.path.join(home_dir, ".diona")
    
    effective_cwd = cwd or diona_dir
    
    config = ShellConfig(
        cwd_whitelist=[diona_dir, effective_cwd],
        command_blacklist=[],  # Empty blacklist for skill scripts
        allow_absolute_paths=True,
        block_home_directory=False,
        expand_home_directory=False,
    )
    
    return ShellCommander(config)


@function_tool
async def skill_script_tool(
    skill_name: str,
    script_name: str,
    args: str = "",
    cwd: str = None,
    timeout: int = 60,
) -> str:
    """Execute a script from a skill.
    
    This tool loads and executes scripts bundled within skills. The script
    location is determined by the skill module, not by user input.
    
    SECURITY: Scripts must come from registered skills, not user-provided content.
    
    Args:
        skill_name: Name of the skill containing the script
        script_name: Name of the script file to execute (e.g., "helper.py")
        args: Command line arguments to pass to the script
        cwd: Working directory (defaults to ~/.diona/)
        timeout: Execution timeout in seconds (default: 60)
    
    Returns:
        Script execution output (stdout and stderr) or error message
    """
    skill = get_skill(skill_name)
    
    if not skill:
        return f"Error: Skill '{skill_name}' not found"
    
    script_content = skill.get_script(script_name)
    
    if script_content is None:
        available = skill.list_scripts()
        if available:
            return f"Error: Script '{script_name}' not found in skill '{skill_name}'. Available scripts: {', '.join(available)}"
        return f"Error: Skill '{skill_name}' has no scripts"
    
    temp_script_path = None
    try:
        import tempfile
        
        with tempfile.NamedTemporaryFile(
            mode='w', 
            suffix=os.path.splitext(script_name)[1],
            delete=False,
            encoding='utf-8'
        ) as f:
            f.write(script_content)
            temp_script_path = f.name
        
        shell = _get_unrestricted_shell(cwd)
        
        ext = os.path.splitext(script_name)[1].lower()
        
        if ext == '.py':
            cmd = f'python "{temp_script_path}" {args}'
        elif ext == '.js':
            cmd = f'node "{temp_script_path}" {args}'
        elif ext == '.sh':
            cmd = f'bash "{temp_script_path}" {args}'
        elif ext == '.bat' or ext == '.cmd':
            cmd = f'cmd /c "{temp_script_path}" {args}'
        elif ext == '.ps1':
            cmd = f'powershell -ExecutionPolicy Bypass -File "{temp_script_path}" {args}'
        else:
            cmd = f'"{temp_script_path}" {args}'
        
        returncode, stdout, stderr = shell.execute(cmd, cwd or skill.base_path, timeout)
        
        output = stdout
        if stderr:
            if output:
                output += "\n\nStderr:\n" + stderr
            else:
                output = "Stderr:\n" + stderr
        
        if not output:
            output = f"(Script executed successfully. Return code: {returncode})"
        
        return output
        
    except Exception as e:
        return f"Error executing script: {str(e)}"
    
    finally:
        if temp_script_path and os.path.exists(temp_script_path):
            try:
                os.unlink(temp_script_path)
            except Exception:
                pass
