// fish_test_helper is a little program with no fish dependencies that acts like certain other
// programs, allowing fish to test its behavior.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static void become_foreground_then_print_stderr() {
    if (tcsetpgrp(STDOUT_FILENO, getpgrp()) < 0) {
        perror("tcsetgrp");
        exit(EXIT_FAILURE);
    }
    usleep(1000000 / 4);  //.25 secs
    fprintf(stderr, "become_foreground_then_print_stderr done\n");
}

static void report_foreground() {
    int was_fg = -1;
    const auto grp = getpgrp();
    for (;;) {
        int is_fg = (tcgetpgrp(STDIN_FILENO) == grp);
        if (is_fg != was_fg) {
            was_fg = is_fg;
            if (fputs(is_fg ? "foreground\n" : "background\n", stderr) < 0) {
                return;
            }
        }
        usleep(1000000 / 2);
    }
}

static void sigint_parent() {
    // SIGINT the parent after 1 second, then exit
    int parent = getppid();
    usleep(1000000 / 4);  //.25 secs
    kill(parent, SIGINT);
    fprintf(stderr, "Sent SIGINT to %d\n", parent);
}

static void print_stdout_stderr() {
    fprintf(stdout, "stdout\n");
    fprintf(stderr, "stderr\n");
    fflush(nullptr);
}

int main(int argc, char *argv[]) {
    if (argc <= 1) {
        fprintf(stderr, "No commands given.\n");
        return 0;
    }
    for (int i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "become_foreground_then_print_stderr")) {
            become_foreground_then_print_stderr();
        } else if (!strcmp(argv[i], "report_foreground")) {
            report_foreground();
        } else if (!strcmp(argv[i], "sigint_parent")) {
            sigint_parent();
        } else if (!strcmp(argv[i], "print_stdout_stderr")) {
            print_stdout_stderr();
        } else {
            fprintf(stderr, "%s: Unknown command: %s\n", argv[0], argv[i]);
            return EXIT_FAILURE;
        }
    }
    return 0;
}
