////////////////////////////////////////////////////////////////////////////////
// BGProcess.cpp
// Copyright Bjoern Ganster
////////////////////////////////////////////////////////////////////////////////

#include "BGProcess.h"
#include "BGStringTemplates.h"

#include <iostream>
//#include <processthreadsapi.h>

// Constructor
BGProcess::BGProcess()
: VirtualClass("BGProcess", BGProcessID),
  mExitCode(0)
{
}

// Run command cmd, with dir as working directory
// Returns true if the process was started successfully
// This call returns only when the external process finishes
bool BGProcess::run(const BGCPString& dir, const BGCPString& cmd)
{
	#ifdef _WIN32
	mErrors.clear();
	BGCPString cmdCpy = cmd;
	BGCPString dirCpy = dir;

	size_t cmdBufLen = cmd.getCharCount()+1;
	mCmdLine.reset(new wchar_t[cmdBufLen]);
	bgstrcpy(mCmdLine.get(), cmdCpy.getAsPath(), cmdBufLen);

	PROCESS_INFORMATION processInfo;
	ZeroMemory(&processInfo, sizeof(processInfo));
	STARTUPINFOW startInfo;
	ZeroMemory(&startInfo, sizeof(startInfo));
	startInfo.cb = sizeof(startInfo);
	BOOL processCreated = 
		CreateProcessW (NULL, mCmdLine.get(), NULL, NULL, false, 
			NORMAL_PRIORITY_CLASS, NULL, dirCpy.getAsPath(), &startInfo, &processInfo);

	// Wait for process to complete
	if (processCreated) {
		do {
			if (!GetExitCodeProcess(processInfo.hProcess, &mExitCode)) {
				COUT << "Unable to obtain process status" << std::endl;
				return false;
			}
		} while (mExitCode == STILL_ACTIVE);

		COUT << "Process ended with code " << mExitCode << std::endl;
		return true;
	} else {
		mErrors = BGCPString::getOSError();
		return false;
	}
	#else
	return false;
	#endif
}
