const { execFile } = require("child_process");

const RELAUNCH_DELAY_SECONDS = 2;
const RELAUNCH_ENVIRONMENT = [
    "DBUS_SESSION_BUS_ADDRESS",
    "DESKTOP_SESSION",
    "DISPLAY",
    "GDMSESSION",
    "GDM_LANG",
    "GNOME_SHELL_SESSION_MODE",
    "HOME",
    "LANG",
    "LOGNAME",
    "PATH",
    "QT_IM_MODULE",
    "SESSION_MANAGER",
    "SHELL",
    "SSH_AUTH_SOCK",
    "USER",
    "USERNAME",
    "WAYLAND_DISPLAY",
    "XAUTHORITY",
    "XDG_CURRENT_DESKTOP",
    "XDG_DATA_DIRS",
    "XDG_MENU_PREFIX",
    "XDG_RUNTIME_DIR",
    "XDG_SESSION_CLASS",
    "XDG_SESSION_DESKTOP",
    "XDG_SESSION_TYPE",
    "XMODIFIERS",
];

function getWidevineRelaunchCommand({
    argv = process.argv,
    env = process.env,
    pid = process.pid,
} = {}) {
    const environment = Object.keys(env)
        .filter((name) => RELAUNCH_ENVIRONMENT.includes(name)
            || name.startsWith("LC_")
            || name.endsWith("_PROXY")
            || name.endsWith("_proxy"))
        .sort()
        .map((name) => `--setenv=${name}`);

    return {
        file: "systemd-run",
        args: [
            "--user",
            "--quiet",
            "--collect",
            "--service-type=exec",
            "--expand-environment=no",
            "--same-dir",
            `--unit=swai-widevine-restart-${pid}`,
            `--on-active=${RELAUNCH_DELAY_SECONDS}s`,
            "--timer-property=AccuracySec=100ms",
            ...environment,
            ...argv,
        ],
    };
}

function scheduleWidevineRelaunch(options = {}, execFileImplementation = execFile) {
    const command = getWidevineRelaunchCommand(options);

    return new Promise((resolve, reject) => {
        execFileImplementation(
            command.file,
            command.args,
            { env: options.env || process.env },
            (error, _stdout, stderr) => {
                if (error) {
                    const detail = stderr?.trim();
                    if (detail) error.message = `${error.message}: ${detail}`;
                    reject(error);
                    return;
                }
                resolve();
            },
        );
    });
}

module.exports = { getWidevineRelaunchCommand, scheduleWidevineRelaunch };
