/*-------------------------------------------------------------------------
 * drawElements Utility Library
 * ----------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Process abstraction.
 *//*--------------------------------------------------------------------*/

#include "deProcess.h"
#include "deMemory.h"
#include "deString.h"

#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_SYMBIAN)

#include "deCommandLine.h"

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>

typedef enum ProcessState_e
{
	PROCESSSTATE_NOT_STARTED = 0,
	PROCESSSTATE_RUNNING,
	PROCESSSTATE_FINISHED,

	PROCESSSTATE_LAST
} ProcessState;

struct deProcess_s
{
	ProcessState	state;
	int				exitCode;
	char*			lastError;

	pid_t			pid;
	deFile*			standardIn;
	deFile*			standardOut;
	deFile*			standardErr;
};

static void die (int statusPipe, const char* message)
{
	size_t	msgLen	= strlen(message);
	int		res		= 0;

	printf("Process launch failed: %s\n", message);
	res = (int)write(statusPipe, message, msgLen+1);
	DE_UNREF(res); /* No need to check result. */
	exit(-1);
}

static void dieLastError (int statusPipe, const char* message)
{
	char	msgBuf[256];
	int		lastErr	= errno;
	deSprintf(msgBuf, sizeof(msgBuf), "%s, error %d: %s", message, lastErr, strerror(lastErr));
	die(statusPipe, msgBuf);
}

DE_INLINE deBool beginsWithPath (const char* fileName, const char* pathPrefix)
{
	size_t pathLen = strlen(pathPrefix);

	/* Strip trailing / */
	while (pathLen > 0 && pathPrefix[pathLen-1] == '/')
		pathLen -= 1;

	return pathLen > 0 && deMemoryEqual(fileName, pathPrefix, pathLen) && fileName[pathLen] == '/';
}

static void stripLeadingPath (char* fileName, const char* pathPrefix)
{
	size_t pathLen		= strlen(pathPrefix);
	size_t fileNameLen	= strlen(fileName);

	DE_ASSERT(beginsWithPath(fileName, pathPrefix));

	/* Strip trailing / */
	while (pathLen > 0 && pathPrefix[pathLen-1] == '/')
		pathLen -= 1;

	DE_ASSERT(pathLen > 0);
	DE_ASSERT(fileName[pathLen] == '/');

	memmove(&fileName[0], &fileName[0]+pathLen+1, fileNameLen-pathLen);
}

/* Doesn't return on success. */
static void execProcess (const char* commandLine, const char* workingDirectory, int statusPipe)
{
	deCommandLine*	cmdLine		= deCommandLine_parse(commandLine);
	char**			argList		= cmdLine ? (char**)deCalloc(sizeof(char*)*((size_t)cmdLine->numArgs+1)) : DE_NULL;

	if (!cmdLine || !argList)
		die(statusPipe, "Command line parsing failed (out of memory)");

	if (workingDirectory && chdir(workingDirectory) != 0)
		dieLastError(statusPipe, "chdir() failed");

	{
		int argNdx;
		for (argNdx = 0; argNdx < cmdLine->numArgs; argNdx++)
			argList[argNdx] = cmdLine->args[argNdx];
		argList[argNdx] = DE_NULL; /* Terminate with 0. */
	}

	if (workingDirectory && beginsWithPath(argList[0], workingDirectory))
		stripLeadingPath(argList[0], workingDirectory);

	execv(argList[0], argList);

	/* Failed. */
	dieLastError(statusPipe, "execv() failed");
}

deProcess* deProcess_create (void)
{
	deProcess* process = (deProcess*)deCalloc(sizeof(deProcess));
	if (!process)
		return DE_FALSE;

	process->state = PROCESSSTATE_NOT_STARTED;

	return process;
}

static void deProcess_cleanupHandles (deProcess* process)
{
	if (process->standardIn)
		deFile_destroy(process->standardIn);

	if (process->standardOut)
		deFile_destroy(process->standardOut);

	if (process->standardErr)
		deFile_destroy(process->standardErr);

	process->pid			= 0;
	process->standardIn		= DE_NULL;
	process->standardOut	= DE_NULL;
	process->standardErr	= DE_NULL;
}

void deProcess_destroy (deProcess* process)
{
	/* Never leave child processes running. Otherwise we'll have zombies. */
	if (deProcess_isRunning(process))
	{
		deProcess_kill(process);
		deProcess_waitForFinish(process);
	}

	deProcess_cleanupHandles(process);
	deFree(process->lastError);
	deFree(process);
}

const char* deProcess_getLastError (const deProcess* process)
{
	return process->lastError ? process->lastError : "No error";
}

int deProcess_getExitCode (const deProcess* process)
{
	return process->exitCode;
}

static deBool deProcess_setError (deProcess* process, const char* error)
{
	if (process->lastError)
	{
		deFree(process->lastError);
		process->lastError = DE_NULL;
	}

	process->lastError = deStrdup(error);
	return process->lastError != DE_NULL;
}

static deBool deProcess_setErrorFromErrno (deProcess* process, const char* message)
{
	char	msgBuf[256];
	int		lastErr		= errno;
	deSprintf(msgBuf, sizeof(msgBuf), "%s, error %d: %s", message, lastErr, strerror(lastErr));
	return deProcess_setError(process, message);
}

static void closePipe (int p[2])
{
	if (p[0] >= 0)
		close(p[0]);
	if (p[1] >= 0)
		close(p[1]);
}

deBool deProcess_start (deProcess* process, const char* commandLine, const char* workingDirectory)
{
	pid_t		pid				= 0;
	int			pipeIn[2]		= { -1, -1 };
	int			pipeOut[2]		= { -1, -1 };
	int			pipeErr[2]		= { -1, -1 };
	int			statusPipe[2]	= { -1, -1 };

	if (process->state == PROCESSSTATE_RUNNING)
	{
		deProcess_setError(process, "Process already running");
		return DE_FALSE;
	}
	else if (process->state == PROCESSSTATE_FINISHED)
	{
		deProcess_cleanupHandles(process);
		process->state = PROCESSSTATE_NOT_STARTED;
	}

	if (pipe(pipeIn) < 0 || pipe(pipeOut) < 0 || pipe(pipeErr) < 0 || pipe(statusPipe) < 0)
	{
		deProcess_setErrorFromErrno(process, "pipe() failed");

		closePipe(pipeIn);
		closePipe(pipeOut);
		closePipe(pipeErr);
		closePipe(statusPipe);

		return DE_FALSE;
	}

	pid = fork();

	if (pid < 0)
	{
		deProcess_setErrorFromErrno(process, "fork() failed");

		closePipe(pipeIn);
		closePipe(pipeOut);
		closePipe(pipeErr);
		closePipe(statusPipe);

		return DE_FALSE;
	}

	if (pid == 0)
	{
		/* Child process. */

		/* Close unused endpoints. */
		close(pipeIn[1]);
		close(pipeOut[0]);
		close(pipeErr[0]);
		close(statusPipe[0]);

		/* Set status pipe to close on exec(). That way parent will know that exec() succeeded. */
		if (fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC) != 0)
			dieLastError(statusPipe[1], "Failed to set FD_CLOEXEC");

		/* Map stdin. */
		if (pipeIn[0] != STDIN_FILENO &&
			dup2(pipeIn[0], STDIN_FILENO) != STDIN_FILENO)
			dieLastError(statusPipe[1], "dup2() failed");
		close(pipeIn[0]);

		/* Stdout. */
		if (pipeOut[1] != STDOUT_FILENO &&
			dup2(pipeOut[1], STDOUT_FILENO) != STDOUT_FILENO)
			dieLastError(statusPipe[1], "dup2() failed");
		close(pipeOut[1]);

		/* Stderr. */
		if (pipeErr[1] != STDERR_FILENO &&
			dup2(pipeErr[1], STDERR_FILENO) != STDERR_FILENO)
			dieLastError(statusPipe[1], "dup2() failed");
		close(pipeErr[1]);

		/* Doesn't return. */
		execProcess(commandLine, workingDirectory, statusPipe[1]);
	}
	else
	{
		/* Parent process. */

		/* Check status. */
		{
			char	errBuf[256];
			ssize_t	result = 0;

			close(statusPipe[1]);
			while ((result = read(statusPipe[0], errBuf, 1)) == -1)
				if (errno != EAGAIN && errno != EINTR) break;

			if (result > 0)
			{
				int procStatus = 0;

				/* Read full error msg. */
				int errPos = 1;
				while (errPos < DE_LENGTH_OF_ARRAY(errBuf))
				{
					result = read(statusPipe[0], errBuf+errPos, 1);
					if (result == -1)
						break; /* Done. */

					errPos += 1;
				}

				/* Make sure str is null-terminated. */
				errBuf[errPos] = 0;

				/* Close handles. */
				close(statusPipe[0]);
				closePipe(pipeIn);
				closePipe(pipeOut);
				closePipe(pipeErr);

				/* Run waitpid to clean up zombie. */
				waitpid(pid, &procStatus, 0);

				deProcess_setError(process, errBuf);

				return DE_FALSE;
			}

			/* Status pipe is not needed. */
			close(statusPipe[0]);
		}

		/* Set running state. */
		process->pid		= pid;
		process->state		= PROCESSSTATE_RUNNING;

		/* Stdin, stdout. */
		close(pipeIn[0]);
		close(pipeOut[1]);
		close(pipeErr[1]);

		process->standardIn		= deFile_createFromHandle((deUintptr)pipeIn[1]);
		process->standardOut	= deFile_createFromHandle((deUintptr)pipeOut[0]);
		process->standardErr	= deFile_createFromHandle((deUintptr)pipeErr[0]);

		if (!process->standardIn)
			close(pipeIn[1]);

		if (!process->standardOut)
			close(pipeOut[0]);

		if (!process->standardErr)
			close(pipeErr[0]);
	}

	return DE_TRUE;
}

deBool deProcess_isRunning (deProcess* process)
{
	if (process->state == PROCESSSTATE_RUNNING)
	{
		int status = 0;

		if (waitpid(process->pid, &status, WNOHANG) == 0)
			return DE_TRUE; /* No status available. */

		if (WIFEXITED(status) || WIFSIGNALED(status))
		{
			/* Child has finished. */
			process->state = PROCESSSTATE_FINISHED;
			return DE_FALSE;
		}
		else
			return DE_TRUE;
	}
	else
		return DE_FALSE;
}

deBool deProcess_waitForFinish (deProcess* process)
{
	int		status = 0;
	pid_t	waitResult;

	if (process->state != PROCESSSTATE_RUNNING)
	{
		deProcess_setError(process, "Process is not running");
		return DE_FALSE;
	}

	/* \note [pyry] Crazy hack for OS X Lion. Stupid Apple. */
	while ((waitResult = waitpid(process->pid, &status, 0)) != process->pid)
		if (errno != ENOENT) break;

	if (waitResult != process->pid)
	{
		deProcess_setErrorFromErrno(process, "waitpid() failed");
		return DE_FALSE; /* waitpid() failed. */
	}

	if (!WIFEXITED(status) && !WIFSIGNALED(status))
	{
		deProcess_setErrorFromErrno(process, "waitpid() failed");
		return DE_FALSE; /* Something strange happened. */
	}

	process->exitCode	= WEXITSTATUS(status);
	process->state		= PROCESSSTATE_FINISHED;
	return DE_TRUE;
}

#if (DE_OS == DE_OS_FUCHSIA)
static deBool deProcess_sendSignal (deProcess* process, int sigNum)
{
	deProcess_setError(process, "Fuchsia doesn't support signals");
	(void)sigNum;
	return DE_FALSE;
}
#else
static deBool deProcess_sendSignal (deProcess* process, int sigNum)
{
	if (process->state != PROCESSSTATE_RUNNING)
	{
		deProcess_setError(process, "Process is not running");
		return DE_FALSE;
	}

	if (kill(process->pid, sigNum) == 0)
		return DE_TRUE;
	else
	{
		deProcess_setErrorFromErrno(process, "kill() failed");
		return DE_FALSE;
	}
}
#endif

deBool deProcess_terminate (deProcess* process)
{
	return deProcess_sendSignal(process, SIGTERM);
}

deBool deProcess_kill (deProcess* process)
{
	return deProcess_sendSignal(process, SIGKILL);
}

deFile* deProcess_getStdIn (deProcess* process)
{
	return process->standardIn;
}

deFile* deProcess_getStdOut (deProcess* process)
{
	return process->standardOut;
}

deFile* deProcess_getStdErr (deProcess* process)
{
	return process->standardErr;
}

deBool deProcess_closeStdIn (deProcess* process)
{
	if (process->standardIn)
	{
		deFile_destroy(process->standardIn);
		process->standardIn	= DE_NULL;
		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

deBool deProcess_closeStdOut (deProcess* process)
{
	if (process->standardOut)
	{
		deFile_destroy(process->standardOut);
		process->standardOut = DE_NULL;
		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

deBool deProcess_closeStdErr (deProcess* process)
{
	if (process->standardErr)
	{
		deFile_destroy(process->standardErr);
		process->standardErr = DE_NULL;
		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

#elif (DE_OS == DE_OS_WIN32)

#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <strsafe.h>

typedef enum ProcessState_e
{
	PROCESSSTATE_NOT_STARTED = 0,
	PROCESSSTATE_RUNNING,
	PROCESSSTATE_FINISHED,

	PROCESSSTATE_LAST
} ProcessState;

struct deProcess_s
{
	ProcessState			state;
	char*					lastError;
	int						exitCode;

	PROCESS_INFORMATION		procInfo;
	deFile*					standardIn;
	deFile*					standardOut;
	deFile*					standardErr;
};

static deBool deProcess_setError (deProcess* process, const char* error)
{
	if (process->lastError)
	{
		deFree(process->lastError);
		process->lastError = DE_NULL;
	}

	process->lastError = deStrdup(error);
	return process->lastError != DE_NULL;
}

static deBool deProcess_setErrorFromWin32 (deProcess* process, const char* msg)
{
	DWORD		error	= GetLastError();
	LPSTR		msgBuf;
	char		errBuf[256];

#if defined(UNICODE)
#	error Unicode not supported.
#endif

	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
					  NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msgBuf, 0, DE_NULL) > 0)
	{
		deSprintf(errBuf, sizeof(errBuf), "%s, error %d: %s", msg, error, msgBuf);
		LocalFree(msgBuf);
		return deProcess_setError(process, errBuf);
	}
	else
	{
		/* Failed to get error str. */
		deSprintf(errBuf, sizeof(errBuf), "%s, error %d", msg, error);
		return deProcess_setError(process, errBuf);
	}
}

deProcess* deProcess_create (void)
{
	deProcess* process = (deProcess*)deCalloc(sizeof(deProcess));
	if (!process)
		return DE_NULL;

	process->state = PROCESSSTATE_NOT_STARTED;

	return process;
}

void deProcess_cleanupHandles (deProcess* process)
{
	DE_ASSERT(!deProcess_isRunning(process));

	if (process->standardErr)
		deFile_destroy(process->standardErr);

	if (process->standardOut)
		deFile_destroy(process->standardOut);

	if (process->standardIn)
		deFile_destroy(process->standardIn);

	if (process->procInfo.hProcess)
		CloseHandle(process->procInfo.hProcess);

	if (process->procInfo.hThread)
		CloseHandle(process->procInfo.hThread);

	process->standardErr		= DE_NULL;
	process->standardOut		= DE_NULL;
	process->standardIn			= DE_NULL;
	process->procInfo.hProcess	= DE_NULL;
	process->procInfo.hThread	= DE_NULL;
}

void deProcess_destroy (deProcess* process)
{
	if (deProcess_isRunning(process))
	{
		deProcess_kill(process);
		deProcess_waitForFinish(process);
	}

	deProcess_cleanupHandles(process);
	deFree(process->lastError);
	deFree(process);
}

const char* deProcess_getLastError (const deProcess* process)
{
	return process->lastError ? process->lastError : "No error";
}

int deProcess_getExitCode (const deProcess* process)
{
	return process->exitCode;
}

deBool deProcess_start (deProcess* process, const char* commandLine, const char* workingDirectory)
{
	SECURITY_ATTRIBUTES	securityAttr;
	STARTUPINFO			startInfo;

	/* Pipes. */
	HANDLE		stdInRead	= DE_NULL;
	HANDLE		stdInWrite	= DE_NULL;
	HANDLE		stdOutRead	= DE_NULL;
	HANDLE		stdOutWrite	= DE_NULL;
	HANDLE		stdErrRead	= DE_NULL;
	HANDLE		stdErrWrite	= DE_NULL;

	if (process->state == PROCESSSTATE_RUNNING)
	{
		deProcess_setError(process, "Process already running");
		return DE_FALSE;
	}
	else if (process->state == PROCESSSTATE_FINISHED)
	{
		/* Process finished, clean up old cruft. */
		deProcess_cleanupHandles(process);
		process->state = PROCESSSTATE_NOT_STARTED;
	}

	deMemset(&startInfo, 0, sizeof(startInfo));
	deMemset(&securityAttr, 0, sizeof(securityAttr));

	/* Security attributes for inheriting handle. */
	securityAttr.nLength				= sizeof(SECURITY_ATTRIBUTES);
	securityAttr.bInheritHandle			= TRUE;
	securityAttr.lpSecurityDescriptor	= DE_NULL;

	/* Create pipes. \todo [2011-10-03 pyry] Clean up handles on error! */
	if (!CreatePipe(&stdInRead, &stdInWrite, &securityAttr, 0) ||
		!SetHandleInformation(stdInWrite, HANDLE_FLAG_INHERIT, 0))
	{
		deProcess_setErrorFromWin32(process, "CreatePipe() failed");
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		return DE_FALSE;
	}

	if (!CreatePipe(&stdOutRead, &stdOutWrite, &securityAttr, 0) ||
		!SetHandleInformation(stdOutRead, HANDLE_FLAG_INHERIT, 0))
	{
		deProcess_setErrorFromWin32(process, "CreatePipe() failed");
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		CloseHandle(stdOutRead);
		CloseHandle(stdOutWrite);
		return DE_FALSE;
	}

	if (!CreatePipe(&stdErrRead, &stdErrWrite, &securityAttr, 0) ||
		!SetHandleInformation(stdErrRead, HANDLE_FLAG_INHERIT, 0))
	{
		deProcess_setErrorFromWin32(process, "CreatePipe() failed");
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		CloseHandle(stdOutRead);
		CloseHandle(stdOutWrite);
		CloseHandle(stdErrRead);
		CloseHandle(stdErrWrite);
		return DE_FALSE;
	}

	/* Setup startup info. */
	startInfo.cb = sizeof(startInfo);
	startInfo.hStdError		 = stdErrWrite;
	startInfo.hStdOutput	 = stdOutWrite;
	startInfo.hStdInput		 = stdInRead;
	startInfo.dwFlags		|= STARTF_USESTDHANDLES;

	if (!CreateProcess(DE_NULL, (LPTSTR)commandLine, DE_NULL, DE_NULL, TRUE /* inherit handles */, 0, DE_NULL, workingDirectory, &startInfo, &process->procInfo))
	{
		/* Store error info. */
		deProcess_setErrorFromWin32(process, "CreateProcess() failed");

		/* Close all handles. */
		CloseHandle(stdInRead);
		CloseHandle(stdInWrite);
		CloseHandle(stdOutRead);
		CloseHandle(stdOutWrite);
		CloseHandle(stdErrRead);
		CloseHandle(stdErrWrite);

		return DE_FALSE;
	}

	process->state = PROCESSSTATE_RUNNING;

	/* Close our ends of handles.*/
	CloseHandle(stdErrWrite);
	CloseHandle(stdOutWrite);
	CloseHandle(stdInRead);

	/* Construct stdio file objects \note May fail, not detected. */
	process->standardIn		= deFile_createFromHandle((deUintptr)stdInWrite);
	process->standardOut	= deFile_createFromHandle((deUintptr)stdOutRead);
	process->standardErr	= deFile_createFromHandle((deUintptr)stdErrRead);

	return DE_TRUE;
}

deBool deProcess_isRunning (deProcess* process)
{
	if (process->state == PROCESSSTATE_RUNNING)
	{
		int exitCode;
		BOOL result = GetExitCodeProcess(process->procInfo.hProcess, (LPDWORD)&exitCode);

		if (result != TRUE)
		{
			deProcess_setErrorFromWin32(process, "GetExitCodeProcess() failed");
			return DE_FALSE;
		}

		if (exitCode == STILL_ACTIVE)
			return DE_TRUE;
		else
		{
			/* Done. */
			process->exitCode	= exitCode;
			process->state		= PROCESSSTATE_FINISHED;
			return DE_FALSE;
		}
	}
	else
		return DE_FALSE;
}

deBool deProcess_waitForFinish (deProcess* process)
{
	if (process->state == PROCESSSTATE_RUNNING)
	{
		if (WaitForSingleObject(process->procInfo.hProcess, INFINITE) != WAIT_OBJECT_0)
		{
			deProcess_setErrorFromWin32(process, "WaitForSingleObject() failed");
			return DE_FALSE;
		}
		return !deProcess_isRunning(process);
	}
	else
	{
		deProcess_setError(process, "Process is not running");
		return DE_FALSE;
	}
}

static deBool stopProcess (deProcess* process, deBool kill)
{
	if (process->state == PROCESSSTATE_RUNNING)
	{
		if (!TerminateProcess(process->procInfo.hProcess, kill ? -1 : 0))
		{
			deProcess_setErrorFromWin32(process, "TerminateProcess() failed");
			return DE_FALSE;
		}
		else
			return DE_TRUE;
	}
	else
	{
		deProcess_setError(process, "Process is not running");
		return DE_FALSE;
	}
}

deBool deProcess_terminate (deProcess* process)
{
	return stopProcess(process, DE_FALSE);
}

deBool deProcess_kill (deProcess* process)
{
	return stopProcess(process, DE_TRUE);
}

deFile* deProcess_getStdIn (deProcess* process)
{
	return process->standardIn;
}

deFile* deProcess_getStdOut (deProcess* process)
{
	return process->standardOut;
}

deFile* deProcess_getStdErr (deProcess* process)
{
	return process->standardErr;
}

deBool deProcess_closeStdIn (deProcess* process)
{
	if (process->standardIn)
	{
		deFile_destroy(process->standardIn);
		process->standardIn	= DE_NULL;
		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

deBool deProcess_closeStdOut (deProcess* process)
{
	if (process->standardOut)
	{
		deFile_destroy(process->standardOut);
		process->standardOut = DE_NULL;
		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

deBool deProcess_closeStdErr (deProcess* process)
{
	if (process->standardErr)
	{
		deFile_destroy(process->standardErr);
		process->standardErr = DE_NULL;
		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

#else
#	error Implement deProcess for your OS.
#endif
