#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include "n_os_tr_tui.h"

static int run_systemctl(char* const argv[]) {
    pid_t pid;
    int status = 0;

    if (systemd_is_simulation_mode()) {
        return 0;
    }

    if (access("/bin/systemctl", X_OK) != 0) {
        return -1;
    }

    pid = fork();
    if (pid < 0) {
        return -1;
    }

    if (pid == 0) {
        execv("/bin/systemctl", argv);
        _exit(127);
    }

    if (waitpid(pid, &status, 0) < 0) {
        return -1;
    }

    if (WIFEXITED(status)) {
        return WEXITSTATUS(status);
    }

    return -1;
}

int systemd_is_simulation_mode(void) {
    const char* v = getenv("NOSTR_TUI_SIMULATE_SYSTEMCTL");
    return (v && strcmp(v, "1") == 0) ? 1 : 0;
}

int systemd_unit_is_active(const char* unit, int* is_active) {
    char* const argv[] = {
        "/bin/systemctl", "is-active", "--quiet", (char*)unit, NULL
    };
    int rc;

    if (!unit || !is_active) return N_OS_TR_TUI_ERR;

    if (systemd_is_simulation_mode()) {
        *is_active = 0;
        return N_OS_TR_TUI_OK;
    }

    rc = run_systemctl(argv);
    if (rc < 0) return N_OS_TR_TUI_ERR;

    *is_active = (rc == 0) ? 1 : 0;
    return N_OS_TR_TUI_OK;
}

int systemd_unit_start(const char* unit, char* err_out, size_t err_out_len) {
    char* const argv[] = {
        "/bin/systemctl", "start", (char*)unit, NULL
    };
    int rc;

    if (!unit) return N_OS_TR_TUI_ERR;

    rc = run_systemctl(argv);
    if (rc == 0) return N_OS_TR_TUI_OK;

    if (err_out && err_out_len > 0) {
        snprintf(err_out, err_out_len, "systemctl start failed for %s (rc=%d, errno=%d)", unit, rc, errno);
    }
    return N_OS_TR_TUI_ERR;
}

int systemd_unit_stop(const char* unit, char* err_out, size_t err_out_len) {
    char* const argv[] = {
        "/bin/systemctl", "stop", (char*)unit, NULL
    };
    int rc;

    if (!unit) return N_OS_TR_TUI_ERR;

    rc = run_systemctl(argv);
    if (rc == 0) return N_OS_TR_TUI_OK;

    if (err_out && err_out_len > 0) {
        snprintf(err_out, err_out_len, "systemctl stop failed for %s (rc=%d, errno=%d)", unit, rc, errno);
    }
    return N_OS_TR_TUI_ERR;
}
