#!/usr/bin/python3
"""motel-compat-run — launch an installed Windows application.

This is what the generated .desktop entries call. It exists so the menu entry
does not encode a Wine command line: when a prefix needs different settings
later, a catalogue update changes behaviour without rewriting every entry the
user already has.
"""
from __future__ import annotations

import logging
import os
import sys
from pathlib import Path

sys.path.insert(0, "/usr/share/motel/compat")

import prefix  # noqa: E402
from ui import show_error  # noqa: E402

logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
log = logging.getLogger("motel-compat-run")


def main(argv: list[str]) -> int:
    if len(argv) < 2:
        print("usage: motel-compat-run <app-id> [arguments...]", file=sys.stderr)
        return 2

    app_id = argv[1]
    extra_args = argv[2:]

    try:
        info = next(
            (p for p in prefix.list_prefixes() if p.app_id == app_id), None
        )
    except prefix.PrefixError as exc:
        show_error("Could not start the application", str(exc))
        return 1

    if info is None:
        show_error(
            "Application not found",
            f"“{app_id}” is not installed.\n\n"
            "It may have been removed in Windows Applications.",
        )
        return 1

    if not info.installed_exe or not Path(info.installed_exe).is_file():
        show_error(
            f"Could not start {info.name}",
            "The program file is missing. The application may have been "
            "partially removed.\n\n"
            "You can remove and reinstall it in Windows Applications.",
        )
        return 1

    env = prefix._wine_env(info)

    if prefix.effective_runtime(info.runtime) == "proton":
        cmd = ["umu-run", info.installed_exe, *extra_args]
        env.setdefault("GAMEID", info.app_id)
    else:
        cmd = ["wine", info.installed_exe, *extra_args]

    # Replace this process rather than waiting on the child: the launcher
    # should not linger in the process list for the life of the application.
    try:
        os.execvpe(cmd[0], cmd, env)
    except OSError as exc:
        show_error(
            f"Could not start {info.name}",
            f"{cmd[0]} could not be run: {exc}",
        )
        return 1


if __name__ == "__main__":
    sys.exit(main(sys.argv))
