import subprocess
import logging
from typing import final

from .fatal_handling import tomte_exit

logger = logging.getLogger(__name__)


@final
class _Command:
    def __init__(self, cmd: list[str], timeout: int) -> None:
        """
        Run a system command with timeout and full error handling.
        If a timeout occurs → FATAL → exit(1).
        """

        logger.debug(f"Executing command: {' '.join(cmd)} with timeout={timeout}s")

        try:
            proc = subprocess.run(
                cmd, capture_output=True, text=True, timeout=timeout, check=False
            )

            stdout = proc.stdout.strip()
            stderr = proc.stderr.strip()

            self.success = True
            self.returncode = proc.returncode
            self.stdout = stdout
            self.stderr = stderr

        except subprocess.TimeoutExpired:
            logger.critical(f"Command timed out after {timeout}s: {' '.join(cmd)}")
            tomte_exit(1)

        except FileNotFoundError:
            logger.error(f"Command not found: {cmd[0]}")
            self.success = False
            self.returncode = None
            self.stdout = ""
            self.stderr = f"{cmd[0]} not found"

        except Exception as e:
            logger.exception(f"Unexpected error while running: {' '.join(cmd)}")
            self.success = False
            self.returncode = None
            self.stdout = ""
            self.stderr = str(e)


def update_hardware_information(timeout_seconds: int = 600) -> dict[str, _Command]:
    """
    Runs lspci and lsusb.
    If either command hits the timeout → program exits(1).
    """

    logger.info("Updating hardware information...")

    results = {
        "lspci": _Command(["lspci", "-n"], timeout_seconds),
        "lsusb": _Command(["lsusb"], timeout_seconds),
    }

    logger.info("Hardware information update completed.")
    return results
