import subprocess
import sys
from pathlib import Path

from .color import Colorizer

type CommandList = list[str | Path | int | float]


color = Colorizer()


def run(commands: CommandList, **kwargs) -> subprocess.CompletedProcess[bytes]:
    return subprocess.run(list(map(str, commands)), check=True, capture_output=True, **kwargs)


def capture(commands: CommandList) -> str:
    return (
        subprocess.run(list(map(str, commands)), capture_output=True, check=False)
        .stdout.decode()
        .strip()
    )


def run_with_result(
    commands: CommandList,
    print_output: bool = False,
    fail_on_error: bool = True,
    **kwargs,
) -> tuple[bool, str]:
    _commands: list[str] = list(map(str, commands))
    subproc_result = subprocess.run(_commands, capture_output=True, check=False, **kwargs)
    result = not bool(subproc_result.returncode)
    stdout = subproc_result.stdout.decode().strip()
    stdout = stdout + "\n" * bool(stdout)
    stderr = subproc_result.stderr.decode().strip()
    stderr = stderr + "\n" * bool(stdout)
    bar = "-" * 36
    topbar = f"{'=' * 36} {color.blue('COMMAND')} {'=' * 35}"
    command_literal = " ".join(list(map(str, _commands)))
    msg = (
        f"\n{topbar}\n{color.blue(command_literal)}"
        f"\n\n{bar} {color.green('STDOUT')} {bar}\n{stdout}\n{bar}"
        f" {color.red('STDERR')} {bar}\n{stderr}\n"
    )
    if fail_on_error and not result:
        print(color.red(f"\nCommand failed: {command_literal}'"))
        print(msg)
        sys.exit(1)
    if print_output:
        print()
        print(msg)
    return result, msg
