#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>

static void init_profiler(char *profile_config, int profile_csv,
                          char *profile_log)
{
    // Set to either 1 or 0 (or unset) to enable or disable profiling.
    setenv("COMPUTE_PROFILE", "1", 1);

    // Set to either 1 (set) or 0 (unset) to enable or disable a comma separated
    // version of the log output.
    if (profile_csv) {
        setenv("COMPUTE_PROFILE_CSV=", "1", 1);
    } else {
        setenv("COMPUTE_PROFILE_CSV=", "0", 1);
    }

    // Set to the desired file path for profiling output. If there is no
    // log path specified, the profiler will log data to ./compute_profile.log.
    // In case of multiple devices you can add '%d' in the COMPUTE_PROFILE_LOG
    // name. This will generate separate profiler output files for each device
    // - with '%d' substituted by the device number.
    if (profile_log) {
        setenv("COMPUTE_PROFILE_LOG", profile_log, 1);
    }

    // Used to specify a config file for enabling performance counters in the GPU. 
    setenv("COMPUTE_PROFILE_CONFIG", profile_config, 1);
}

int main(int argc, char **argv)
{
    char *profile_exec = NULL, *profile_config = NULL, *profile_log = NULL;
    int profile_csv = 0, timeout = 1; /* 1s of timeout by default */
    pid_t pid;
    int c;

    if (argc < 3) {
        fprintf(stderr,
                "Usage: %s <profile_exec> <profile_config> [options]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    profile_exec   = argv[1];
    profile_config = argv[2];

    while (1) {
        static struct option long_options[] = {
            {"csv",     no_argument,        0, 'c'},
            {"log",     required_argument,  0, 'l'},
            {"timeout", required_argument,  0, 't'},
            {0, 0, 0, 0}
        };

        /* getopt_long stores the option index here. */
        int option_index = 0;

        argv -= 2;
        argv += 2;
        c = getopt_long(argc, argv, "c:l:t:", long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;

        switch (c) {
            case 'c':
                profile_csv = 1;
                break;
            case 'l':
                profile_log = optarg;
                break;
            case 't':
                timeout = atoi(optarg);
                break;
            case '?':
                /* getopt_long already printed an error message. */
                break;
            default:
                abort ();
        }
    }

    // Init environnement variables in order to enable profiling.
    init_profiler(profile_config, profile_csv, profile_log);

    pid = fork();
    if (pid == 0) {
        execlp(profile_exec, "oceanFFT", NULL);
        if (errno == ENOENT) {
            fprintf(stderr, "No such file or directory.\n");
            exit(EXIT_FAILURE);
        }
    } else {
        sleep(timeout);
        kill(pid, SIGTERM);
    }

    return EXIT_SUCCESS;
}