/* See COPYING.txt for the full license governing this code. */
/**
 * \file windows_process.c 
 *
 * Source file for the process API on windows.
 */


#include <SDL.h>
#include <SDL_test.h>
#include <string.h>
#include <stdlib.h>

#include "SDL_visualtest_process.h"

#if defined(__WIN32__)

void
LogLastError(char* str)
{
    LPVOID buffer;
    DWORD dw = GetLastError();
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|
                    FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer,
                    0, NULL);
    SDLTest_LogError("%s: %s", str, (char*)buffer);
    LocalFree(buffer);
}

int
SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo)
{
    BOOL success;
    char* working_directory;
    char* command_line;
    int path_length, args_length;
    STARTUPINFO sui = {0};
    sui.cb = sizeof(sui);

    if(!file)
    {
        SDLTest_LogError("Path to executable to launched cannot be NULL.");
        return 0;
    }
    if(!pinfo)
    {
        SDLTest_LogError("pinfo cannot be NULL.");
        return 0;
    }

    /* get the working directory of the process being launched, so that
        the process can load any resources it has in it's working directory */
    path_length = SDL_strlen(file);
    if(path_length == 0)
    {
        SDLTest_LogError("Length of the file parameter is zero.");
        return 0;
    }

    working_directory = (char*)SDL_malloc(path_length + 1);
    if(!working_directory)
    {
        SDLTest_LogError("Could not allocate working_directory - malloc() failed.");
        return 0;
    }

    SDL_memcpy(working_directory, file, path_length + 1);
    PathRemoveFileSpec(working_directory);
    if(SDL_strlen(working_directory) == 0)
    {
        SDL_free(working_directory);
        working_directory = NULL;
    }

    /* join the file path and the args string together */
    if(!args)
        args = "";
    args_length = SDL_strlen(args);
    command_line = (char*)SDL_malloc(path_length + args_length + 2);
    if(!command_line)
    {
        SDLTest_LogError("Could not allocate command_line - malloc() failed.");
        return 0;
    }
    SDL_memcpy(command_line, file, path_length);
    command_line[path_length] = ' ';
    SDL_memcpy(command_line + path_length + 1, args, args_length + 1);

    /* create the process */
    success = CreateProcess(NULL, command_line, NULL, NULL, FALSE,
                            NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
                            NULL, working_directory, &sui, &pinfo->pi);
    if(working_directory)
    {
        SDL_free(working_directory);
        working_directory = NULL;
    }
    SDL_free(command_line);
    if(!success)
    {
        LogLastError("CreateProcess() failed");
        return 0;
    }

    return 1;
}

int
SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
    DWORD exit_status;
    BOOL success;

    if(!pinfo)
    {
        SDLTest_LogError("pinfo cannot be NULL");
        return 0;
    }
    if(!ps)
    {
        SDLTest_LogError("ps cannot be NULL");
        return 0;
    }

    /* get the exit code */
    success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
    if(!success)
    {
        LogLastError("GetExitCodeProcess() failed");
        return 0;
    }

    if(exit_status == STILL_ACTIVE)
        ps->exit_status = -1;
    else
        ps->exit_status = exit_status;
    ps->exit_success = 1;
    return 1;
}


int
SDL_IsProcessRunning(SDL_ProcessInfo* pinfo)
{
    DWORD exit_status;
    BOOL success;

    if(!pinfo)
    {
        SDLTest_LogError("pinfo cannot be NULL");
        return -1;
    }

    success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
    if(!success)
    {
        LogLastError("GetExitCodeProcess() failed");
        return -1;
    }
    
    if(exit_status == STILL_ACTIVE)
        return 1;
    return 0;
}

static BOOL CALLBACK
CloseWindowCallback(HWND hwnd, LPARAM lparam)
{
    DWORD pid;
    SDL_ProcessInfo* pinfo;

    pinfo = (SDL_ProcessInfo*)lparam;

    GetWindowThreadProcessId(hwnd, &pid);
    if(pid == pinfo->pi.dwProcessId)
    {
        DWORD result;
        if(!SendMessageTimeout(hwnd, WM_CLOSE, 0, 0, SMTO_BLOCK,
                               1000, &result))
        {
            if(GetLastError() != ERROR_TIMEOUT)
            {
                LogLastError("SendMessageTimeout() failed");
                return FALSE;
            }
        }
    }
    return TRUE;
}

int
SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
    DWORD wait_result;
    if(!pinfo)
    {
        SDLTest_LogError("pinfo argument cannot be NULL");
        return 0;
    }
    if(!ps)
    {
        SDLTest_LogError("ps argument cannot be NULL");
        return 0;
    }

    /* enumerate through all the windows, trying to close each one */
    if(!EnumWindows(CloseWindowCallback, (LPARAM)pinfo))
    {
        SDLTest_LogError("EnumWindows() failed");
        return 0;
    }

    /* wait until the process terminates */
    wait_result = WaitForSingleObject(pinfo->pi.hProcess, 1000);
    if(wait_result == WAIT_FAILED)
    {
        LogLastError("WaitForSingleObject() failed");
        return 0;
    }
    if(wait_result != WAIT_OBJECT_0)
    {
        SDLTest_LogError("Process did not quit.");
        return 0;
    }

    /* get the exit code */
    if(!SDL_GetProcessExitStatus(pinfo, ps))
    {
        SDLTest_LogError("SDL_GetProcessExitStatus() failed");
        return 0;
    }

    return 1;
}

int
SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
    BOOL success;
    DWORD exit_status, wait_result;

    if(!pinfo)
    {
        SDLTest_LogError("pinfo argument cannot be NULL");
        return 0;
    }
    if(!ps)
    {
        SDLTest_LogError("ps argument cannot be NULL");
        return 0;
    }

    /* initiate termination of the process */
    success = TerminateProcess(pinfo->pi.hProcess, 0);
    if(!success)
    {
        LogLastError("TerminateProcess() failed");
        return 0;
    }

    /* wait until the process terminates */
    wait_result = WaitForSingleObject(pinfo->pi.hProcess, INFINITE);
    if(wait_result == WAIT_FAILED)
    {
        LogLastError("WaitForSingleObject() failed");
        return 0;
    }

    /* get the exit code */
    success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
    if(!success)
    {
        LogLastError("GetExitCodeProcess() failed");
        return 0;
    }

    ps->exit_status = exit_status;
    ps->exit_success = 1;

    return 1;
}

#endif
