/*
   Copyright (C) Andrew Tridgell 2002
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "ccache.h"

#ifdef _WIN32
char *argvtos(char **argv)
{
	int i, len;
	char *ptr, *str;

	for (i = 0, len = 0; argv[i]; i++) {
		len += strlen(argv[i]) + 3;
	}

	str = ptr = (char *)malloc(len + 1);
	if (str == NULL)
		return NULL;

	for (i = 0; argv[i]; i++) {
		len = strlen(argv[i]);
		*ptr++ = '"';
		memcpy(ptr, argv[i], len);
		ptr += len;
		*ptr++ = '"';
		*ptr++ = ' ';
	}
	*ptr = 0;

	return str;
}
#endif

/*
  execute a compiler backend, capturing all output to the given paths
  the full path to the compiler to run is in argv[0]
*/
int execute(char **argv, 
	    const char *path_stdout,
	    const char *path_stderr)
{
#ifdef _WIN32

#if 1
	PROCESS_INFORMATION pinfo; 
	STARTUPINFO sinfo;
	BOOL ret; 
	DWORD exitcode;
	char *args;
	HANDLE fd_out, fd_err;
	SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};

	/* TODO: needs moving after possible exit() below, but before stdout is redirected */
	if (ccache_verbose) {
		display_execute_args(argv);
	}

	fd_out = CreateFile(path_stdout, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL, NULL);
	if (fd_out == INVALID_HANDLE_VALUE) {
		return STATUS_NOCACHE;
	}

	fd_err = CreateFile(path_stderr, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL, NULL);
	if (fd_err == INVALID_HANDLE_VALUE) {
		return STATUS_NOCACHE;
	}
   
	ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
	ZeroMemory(&sinfo, sizeof(STARTUPINFO));

	sinfo.cb = sizeof(STARTUPINFO); 
	sinfo.hStdError = fd_err;
	sinfo.hStdOutput = fd_out;
	sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	sinfo.dwFlags |= STARTF_USESTDHANDLES;
 
	args = argvtos(argv);

	ret = CreateProcessA(argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
	                     &sinfo, &pinfo);

	free(args);
	CloseHandle(fd_out);
	CloseHandle(fd_err);

	if (ret == 0)
		return -1;

	WaitForSingleObject(pinfo.hProcess, INFINITE);
	GetExitCodeProcess(pinfo.hProcess, &exitcode);
	CloseHandle(pinfo.hProcess);
	CloseHandle(pinfo.hThread);

	return exitcode;
#else /* possibly slightly faster */
	/* needs fixing to quote commandline options to handle spaces in CCACHE_DIR etc */
	int   status = -2;
	int   fd, std_od = -1, std_ed = -1;

	/* TODO: needs moving after possible exit() below, but before stdout is redirected */
	if (ccache_verbose) {
		display_execute_args(argv);
	}

	unlink(path_stdout);
	std_od = _dup(1);
	fd = _open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
	if (fd == -1) {
		exit(STATUS_NOCACHE);
	}
	_dup2(fd, 1);
	_close(fd);

	unlink(path_stderr);
	fd = _open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
	std_ed = _dup(2);
	if (fd == -1) {
		exit(STATUS_NOCACHE);
	}
	_dup2(fd, 2);
	_close(fd);

	/* Spawn process (_exec* family doesn't return) */
	status = _spawnv(_P_WAIT, argv[0], (const char **)argv);

	/* Restore descriptors */
	if (std_od != -1) _dup2(std_od, 1);
	if (std_ed != -1) _dup2(std_ed, 2);
	_flushall();

	return (status>0);

#endif

#else
	pid_t pid;
	int status;

	pid = fork();
	if (pid == -1) fatal("Failed to fork");
	
	if (pid == 0) {
		int fd;

		/* TODO: needs moving after possible exit() below, but before stdout is redirected */
		if (ccache_verbose) {
			display_execute_args(argv);
		}

		unlink(path_stdout);
		fd = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
		if (fd == -1) {
			exit(STATUS_NOCACHE);
		}
		dup2(fd, 1);
		close(fd);

		unlink(path_stderr);
		fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
		if (fd == -1) {
			exit(STATUS_NOCACHE);
		}
		dup2(fd, 2);
		close(fd);

		exit(execv(argv[0], argv));
	}

	if (waitpid(pid, &status, 0) != pid) {
		fatal("waitpid failed");
	}

	if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
		return -1;
	}

	return WEXITSTATUS(status);
#endif
}


/*
  find an executable by name in $PATH. Exclude any that are links to exclude_name 
*/
char *find_executable(const char *name, const char *exclude_name)
{
#if _WIN32
	(void)exclude_name;
	DWORD ret;
	char namebuf[MAX_PATH];

	ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe",
			  sizeof(namebuf), namebuf, NULL);
	if (ret != 0) {
		return x_strdup(namebuf);
	}

	return NULL;
#else
	char *path;
	char *tok;
	struct stat st1, st2;

	if (*name == '/') {
		return x_strdup(name);
	}

	path = getenv("CCACHE_PATH");
	if (!path) {
		path = getenv("PATH");
	}
	if (!path) {
		cc_log("no PATH variable!?\n");
		stats_update(STATS_ENVIRONMMENT);
		return NULL;
	}

	path = x_strdup(path);
	
	/* search the path looking for the first compiler of the right name
	   that isn't us */
	for (tok=strtok(path,":"); tok; tok = strtok(NULL, ":")) {
		char *fname;
		x_asprintf(&fname, "%s/%s", tok, name);
		/* look for a normal executable file */
		if (access(fname, X_OK) == 0 &&
		    lstat(fname, &st1) == 0 &&
		    stat(fname, &st2) == 0 &&
		    S_ISREG(st2.st_mode)) {
			/* if its a symlink then ensure it doesn't
                           point at something called exclude_name */
			if (S_ISLNK(st1.st_mode)) {
				char *buf = x_realpath(fname);
				if (buf) {
					char *p = str_basename(buf);
					if (strcmp(p, exclude_name) == 0) {
						/* its a link to "ccache" ! */
						free(p);
						free(buf);
						continue;
					}
					free(buf);
					free(p);
				}
			}

			/* found it! */
			free(path);
			return fname;
		}
		free(fname);
	}
	free(path);

	return NULL;
#endif
}

void display_execute_args(char **argv)
{
	if (argv) {
		printf("ccache executing: ");
		while (*argv) {
			printf("%s ", *argv);
			++argv;
		}
		printf("\n");
		fflush(stdout);
	}
}
