#include <windows.h>
#include <stdio.h>
#include "Shlwapi.h"
static void GetEyeTrackerManagerPath(char* path, DWORD size) {
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
    if (!GetEnvironmentVariable("LocalAppData", path, size)) {
        perror("Local App");
        exit(EXIT_FAILURE);
    }
    PathAppend(path, "TobiiProEyeTrackerManager\\app*"); 
    
    hFind = FindFirstFile(path, &FindFileData); 
    if (hFind == INVALID_HANDLE_VALUE) {
        perror("FindFirstFile");
        exit(EXIT_FAILURE);
    } 
    FindClose(hFind);
    PathRemoveFileSpec(path); 
    PathAppend(path, FindFileData.cFileName);
    PathAppend(path, "TobiiProEyeTrackerManager.exe");
}
static void AddArgsToEyeTrackerManagerCall(char* call, DWORD call_size) {
    char* deviceaddress;
        printf("ERROR: %d when trying to get eyetracker!\n", status);
        exit(EXIT_FAILURE);
    }
        printf("ERROR: %d when trying to get address!\n", status);
        exit(EXIT_FAILURE);
    }
    _snprintf(call, call_size,"%s --device-address=%s --mode=%s", call, deviceaddress, "displayarea");
}
static void PrintfLinesStartingWith(HANDLE f, const char* line_start) {
    DWORD bytes_read;
    #define BUF_SIZE 64
    CHAR buf[BUF_SIZE];
    BOOL success = FALSE;
    BOOL found_matching_line_start = FALSE;
    size_t line_start_len = strlen(line_start);
    size_t bytes_to_read = line_start_len;
    if (line_start_len > BUF_SIZE) {
        printf("ERROR: %s longer then BUF_SIZE!\n", line_start);
        exit(EXIT_FAILURE);
    }
    do {
        
        ZeroMemory(buf, sizeof(buf));
        success = ReadFile(f, buf, (DWORD)bytes_to_read, &bytes_read, NULL);
        if (bytes_read == 1 && buf[0] == '\n' ) {  
            found_matching_line_start = FALSE;
            bytes_to_read = line_start_len;
        } else if (bytes_read == line_start_len && !strncmp(buf, line_start, line_start_len)) {
            found_matching_line_start = TRUE;
            bytes_to_read = 1;
        }
        if (found_matching_line_start) {
            printf("%s", buf);
        }
    } while (success || bytes_read != 0);
}
#pragma comment(lib, "Shlwapi.lib")
int main() {
    HANDLE hChildStd_OUT_Rd = NULL;
    HANDLE hChildStd_OUT_Wr = NULL;
    SECURITY_ATTRIBUTES saAttr;
    
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 
    
    if (!CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &saAttr, 0)) {
        perror("StdoutRd CreatePipe"); 
        exit(EXIT_FAILURE);
    }
    
    if (!SetHandleInformation(hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
        perror("Stdout SetHandleInformation");
        exit(EXIT_FAILURE);
    }
    
    char ETM_CALL[MAX_PATH];
    ZeroMemory(ETM_CALL, sizeof(*ETM_CALL)*MAX_PATH);
    GetEyeTrackerManagerPath(ETM_CALL, MAX_PATH);
    AddArgsToEyeTrackerManagerCall(ETM_CALL, MAX_PATH);
    
    
    PROCESS_INFORMATION piProcInfo; 
    STARTUPINFO siStartInfo;
    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
    
    
    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.hStdOutput = hChildStd_OUT_Wr;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
    
    if (!CreateProcess(NULL,
                            ETM_CALL,      
                            NULL,          
                            NULL,          
                            TRUE,          
                            0,             
                            NULL,          
                            NULL,          
                            &siStartInfo,  
                            &piProcInfo)  
    ) {
        perror("Create Process failed!!\n");
        exit(EXIT_FAILURE);
    } 
    
    DWORD exitcode;
    WaitForSingleObject(piProcInfo.hProcess, INFINITE);
    GetExitCodeProcess(piProcInfo.hProcess, &exitcode);
    CloseHandle(hChildStd_OUT_Wr);
    
    
    
    if (exitcode == 0) {
        printf("Eye Tracker Manager was called successfully!\n");
    } else {
        printf("Eye Tracker Manager call returned the error code: %lu\n", exitcode);
        
        PrintfLinesStartingWith(hChildStd_OUT_Rd, "ETM Error:");
    }
    CloseHandle(hChildStd_OUT_Rd);
    CloseHandle(piProcInfo.hProcess);
    CloseHandle(piProcInfo.hThread);
}