"""Shell tool: execute bash / PowerShell commands safely."""

import os
import subprocess

from genworker.config import IS_WINDOWS, BASH_TIMEOUT, USER_HOME, log

DANGEROUS_COMMANDS = [
    # Cross-platform
    "rm -rf /", ":(){:|:&};:", "mkfs", "shutdown",
    # Windows
    "format c:", "del /s /q c:\\",
    "Remove-Item -Recurse -Force C:\\",
    "restart-computer", "stop-computer",
    "Clear-Disk", "Initialize-Disk",
    "Remove-Item -Recurse -Force ~",
    # macOS / Linux
    "rm -rf ~", "rm -rf /*", "dd if=", "diskutil eraseDisk",
    "sudo rm -rf", ":(){ :|:& };:",
]


def _get_shell_command(command: str) -> list:
    if IS_WINDOWS:
        return ["powershell", "-NoProfile", "-Command", command]
    shell = os.environ.get("SHELL", "/bin/sh")
    return [shell, "-c", command]


def execute_bash(inp: dict) -> str:
    command = inp.get("command", "")
    log.info(f"⚡  bash | {command[:200]}")

    if not command.strip():
        return "Error: empty command"

    cmd_lower = command.lower()
    for dangerous in DANGEROUS_COMMANDS:
        if dangerous.lower() in cmd_lower:
            msg = f"⛔ BLOCKED dangerous command: {command[:100]}"
            log.warning(msg)
            return msg

    try:
        result = subprocess.run(
            _get_shell_command(command),
            capture_output=True, text=True,
            timeout=BASH_TIMEOUT,
            cwd=USER_HOME,
            env={**os.environ, "PYTHONIOENCODING": "utf-8"},
        )
        output = ""
        if result.stdout:
            output += result.stdout
        if result.stderr:
            output += f"\n[STDERR] {result.stderr}"
        if result.returncode != 0:
            output += f"\n[EXIT CODE] {result.returncode}"

        if len(output) > 15000:
            output = (
                output[:5000]
                + f"\n\n... [TRUNCATED — {len(output)} chars total. First 5K + last 5K shown] ...\n\n"
                + output[-5000:]
            )

        return output.strip() or "(no output)"

    except subprocess.TimeoutExpired:
        return f"Error: command timed out after {BASH_TIMEOUT}s — try a simpler command or increase BASH_TIMEOUT"
    except Exception as e:
        return f"Error: {e}"
