#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include "git-compat-util.h"

#ifndef PATH_MAX
# define PATH_MAX 4096
#endif

static const char git_usage[] =
	"Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";

/* most gui terms set COLUMNS (although some don't export it) */
static int term_columns(void)
{
	char *col_string = getenv("COLUMNS");
	int n_cols = 0;

	if (col_string && (n_cols = atoi(col_string)) > 0)
		return n_cols;

	return 80;
}

static void oom(void)
{
	fprintf(stderr, "git: out of memory\n");
	exit(1);
}

static inline void mput_char(char c, unsigned int num)
{
	while(num--)
		putchar(c);
}

static struct cmdname {
	size_t len;
	char name[1];
} **cmdname;
static int cmdname_alloc, cmdname_cnt;

static void add_cmdname(const char *name, int len)
{
	struct cmdname *ent;
	if (cmdname_alloc <= cmdname_cnt) {
		cmdname_alloc = cmdname_alloc + 200;
		cmdname = realloc(cmdname, cmdname_alloc * sizeof(*cmdname));
		if (!cmdname)
			oom();
	}
	ent = malloc(sizeof(*ent) + len);
	if (!ent)
		oom();
	ent->len = len;
	memcpy(ent->name, name, len);
	ent->name[len] = 0;
	cmdname[cmdname_cnt++] = ent;
}

static int cmdname_compare(const void *a_, const void *b_)
{
	struct cmdname *a = *(struct cmdname **)a_;
	struct cmdname *b = *(struct cmdname **)b_;
	return strcmp(a->name, b->name);
}

static void pretty_print_string_list(struct cmdname **cmdname, int longest)
{
	int cols = 1;
	int space = longest + 1; /* min 1 SP between words */
	int max_cols = term_columns() - 1; /* don't print *on* the edge */
	int i;

	if (space < max_cols)
		cols = max_cols / space;

	qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare);

	for (i = 0; i < cmdname_cnt; ) {
		int c;
		printf("  ");

		for (c = cols; c && i < cmdname_cnt; i++) {
			printf("%s", cmdname[i]->name);

			if (--c)
				mput_char(' ', space - cmdname[i]->len);
		}
		putchar('\n');
	}
}

static void list_commands(const char *exec_path, const char *pattern)
{
	unsigned int longest = 0;
	char path[PATH_MAX];
	int dirlen;
	DIR *dir = opendir(exec_path);
	struct dirent *de;

	if (!dir) {
		fprintf(stderr, "git: '%s': %s\n", exec_path, strerror(errno));
		exit(1);
	}

	dirlen = strlen(exec_path);
	if (PATH_MAX - 20 < dirlen) {
		fprintf(stderr, "git: insanely long exec-path '%s'\n",
			exec_path);
		exit(1);
	}

	memcpy(path, exec_path, dirlen);
	path[dirlen++] = '/';

	while ((de = readdir(dir)) != NULL) {
		struct stat st;
		int entlen;

		if (strncmp(de->d_name, "git-", 4))
			continue;
		strcpy(path+dirlen, de->d_name);
		if (stat(path, &st) || /* stat, not lstat */
		    !S_ISREG(st.st_mode) ||
		    !(st.st_mode & S_IXUSR))
			continue;

		entlen = strlen(de->d_name);
		if (4 < entlen && !strcmp(de->d_name + entlen - 4, ".exe"))
			entlen -= 4;

		if (longest < entlen)
			longest = entlen;

		add_cmdname(de->d_name + 4, entlen-4);
	}
	closedir(dir);

	printf("git commands available in '%s'\n", exec_path);
	printf("----------------------------");
	mput_char('-', strlen(exec_path));
	putchar('\n');
	pretty_print_string_list(cmdname, longest - 4);
	putchar('\n');
}

#ifdef __GNUC__
static void cmd_usage(const char *exec_path, const char *fmt, ...)
	__attribute__((__format__(__printf__, 2, 3), __noreturn__));
#endif
static void cmd_usage(const char *exec_path, const char *fmt, ...)
{
	if (fmt) {
		va_list ap;

		va_start(ap, fmt);
		printf("git: ");
		vprintf(fmt, ap);
		va_end(ap);
		putchar('\n');
	}
	else
		puts(git_usage);

	putchar('\n');

	if(exec_path)
		list_commands(exec_path, "git-*");

	exit(1);
}

static void prepend_to_path(const char *dir, int len)
{
	char *path, *old_path = getenv("PATH");
	int path_len = len;

	if (!old_path)
		old_path = "/usr/local/bin:/usr/bin:/bin";

	path_len = len + strlen(old_path) + 1;

	path = malloc(path_len + 1);

	memcpy(path, dir, len);
	path[len] = ':';
	memcpy(path + len + 1, old_path, path_len - len);

	setenv("PATH", path, 1);
}

static void show_man_page(char *git_cmd)
{
	char *page;

	if (!strncmp(git_cmd, "git", 3))
		page = git_cmd;
	else {
		int page_len = strlen(git_cmd) + 4;

		page = malloc(page_len + 1);
		strcpy(page, "git-");
		strcpy(page + 4, git_cmd);
		page[page_len] = 0;
	}

	execlp("man", "man", page, NULL);
}

int main(int argc, char **argv, char **envp)
{
	char git_command[PATH_MAX + 1];
	char wd[PATH_MAX + 1];
	int i, len, show_help = 0;
	char *exec_path = getenv("GIT_EXEC_PATH");

	getcwd(wd, PATH_MAX);

	if (!exec_path)
		exec_path = GIT_EXEC_PATH;

	for (i = 1; i < argc; i++) {
		char *arg = argv[i];

		if (strncmp(arg, "--", 2))
			break;

		arg += 2;

		if (!strncmp(arg, "exec-path", 9)) {
			arg += 9;
			if (*arg == '=')
				exec_path = arg + 1;
			else {
				puts(exec_path);
				exit(0);
			}
		}
		else if (!strcmp(arg, "version")) {
			printf("git version %s\n", GIT_VERSION);
			exit(0);
		}
		else if (!strcmp(arg, "help"))
			show_help = 1;
		else if (!show_help)
			cmd_usage(NULL, NULL);
	}

	if (i >= argc || show_help) {
		if (i >= argc)
			cmd_usage(exec_path, NULL);

		show_man_page(argv[i]);
	}

	if (*exec_path != '/') {
		if (!getcwd(git_command, sizeof(git_command))) {
			fprintf(stderr,
				"git: cannot determine current directory");
			exit(1);
		}
		len = strlen(git_command);

		/* Trivial cleanup */
		while (!strncmp(exec_path, "./", 2)) {
			exec_path += 2;
			while (*exec_path == '/')
				exec_path++;
		}
		snprintf(git_command + len, sizeof(git_command) - len,
			 "/%s", exec_path);
	}
	else
		strcpy(git_command, exec_path);
	len = strlen(git_command);
	prepend_to_path(git_command, len);

	len += snprintf(git_command + len, sizeof(git_command) - len,
			"/git-%s", argv[i]);
	if (sizeof(git_command) <= len) {
		fprintf(stderr, "git: command name given is too long.\n");
		exit(1);
	}

	/* execve() can only ever return if it fails */
	execve(git_command, &argv[i], envp);

	if (errno == ENOENT)
		cmd_usage(exec_path, "'%s' is not a git-command", argv[i]);

	fprintf(stderr, "Failed to run command '%s': %s\n",
		git_command, strerror(errno));

	return 1;
}
