#include <system/process.h>
#include <stdexcept>
#include <string>

namespace System
{

Process::Process()
    : processHandle(0)
{
}

Process::~Process()
{
    if (processHandle)
        CloseHandle(processHandle);
}

#ifdef UNICODE

void Process::create(const wchar_t* programPath, const wchar_t* arguments)
{
    if (!programPath || !wcslen(programPath))
        throw std::runtime_error("Program path is invalid.");


    PROCESS_INFORMATION processInfo;
#ifndef _WIN32_WCE
    std::basic_string<wchar_t> cmdLine(programPath);
    if (arguments && wcslen(arguments))
    {
        cmdLine += " ";
        cmdLine += arguments;
    }
    
    STARTUPINFO startupInfo;
    GetStartupInfo(&startupInfo);
    bool ok = CreateProcess(0, cmdLine.c_str(), 0, 0, false, 0, 0, 0, &startupInfo, &processInfo);
#else
    bool ok = CreateProcess(programPath, (WCHAR*)arguments, 0, 0, false, 0, 0, 0, 0, &processInfo);
#endif // _WIN32_WCE
    if (!ok)
        throw std::runtime_error("Cannot create process.");

    CloseHandle(processInfo.hThread);
    processHandle = processInfo.hProcess;    
}

#else

void Process::create(const char* programPath, const char* arguments)
{
    if (!programPath || !strlen(programPath))
        throw std::runtime_error("Program path is invalid.");

    bool ok;
    PROCESS_INFORMATION processInfo;
    STARTUPINFO startupInfo;
    std::string cmdLine(programPath);

    if (arguments && strlen(arguments))
    {
        cmdLine += " ";
        cmdLine += arguments;
    }

    GetStartupInfo(&startupInfo);
    bool ok = CreateProcess(0, cmdLine.c_str(), 0, 0, false, 0, 0, 0, &startupInfo, &processInfo);
    if (!ok)
        throw std::runtime_error("Cannot create process.");

    CloseHandle(processInfo.hThread);
    processHandle = processInfo.hProcess;
}

#endif // UNICODE

void Process::kill()
{
    int exitCode = 9;
    TerminateProcess(processHandle, exitCode);
}

} // namespace System

