from __future__ import annotations

import shutil
import subprocess
from pathlib import Path
import sys
from typing import Any


def run(
    command: str,
    args: list[Any] | None = None,
    cwd: str | None = None,
    *,
    runtime: Any,
) -> dict[str, Any]:
    command_args = [_resolve_command(command), *[str(value) for value in (args or [])]]
    target_cwd = _resolve_cwd(cwd, runtime.workspace_root)
    completed = subprocess.run(
        command_args,
        capture_output=True,
        text=True,
        timeout=runtime.timeout,
        cwd=str(target_cwd),
        shell=False,
        check=False,
    )
    return {
        "stdout": completed.stdout,
        "stderr": completed.stderr,
        "code": completed.returncode,
    }


def _resolve_command(command: str) -> str:
    if command == "python":
        resolved = shutil.which(command)
        if resolved is not None:
            return resolved
        return sys.executable
    return command


def _resolve_cwd(cwd: str | None, workspace_root: Path) -> Path:
    if cwd is None:
        return workspace_root

    candidate = Path(cwd)
    if not candidate.is_absolute():
        candidate = workspace_root / candidate
    return candidate.resolve()
