#include "git-compat-util.h"
#include "diagnose.h"
#include "compat/disk.h"
#include "archive.h"
#include "dir.h"
#include "help.h"
#include "gettext.h"
#include "hex.h"
#include "strvec.h"
#include "object-store-ll.h"
#include "packfile.h"
#include "parse-options.h"
#include "write-or-die.h"

struct archive_dir {
	const char *path;
	int recursive;
};

struct diagnose_option {
	enum diagnose_mode mode;
	const char *option_name;
};

static struct diagnose_option diagnose_options[] = {
	{ DIAGNOSE_STATS, "stats" },
	{ DIAGNOSE_ALL, "all" },
};

int option_parse_diagnose(const struct option *opt, const char *arg, int unset)
{
	int i;
	enum diagnose_mode *diagnose = opt->value;

	if (!arg) {
		*diagnose = unset ? DIAGNOSE_NONE : DIAGNOSE_STATS;
		return 0;
	}

	for (i = 0; i < ARRAY_SIZE(diagnose_options); i++) {
		if (!strcmp(arg, diagnose_options[i].option_name)) {
			*diagnose = diagnose_options[i].mode;
			return 0;
		}
	}

	return error(_("invalid --%s value '%s'"), opt->long_name, arg);
}

static void dir_file_stats_objects(const char *full_path,
				   size_t full_path_len UNUSED,
				   const char *file_name, void *data)
{
	struct strbuf *buf = data;
	struct stat st;

	if (!stat(full_path, &st))
		strbuf_addf(buf, "%-70s %16" PRIuMAX "\n", file_name,
			    (uintmax_t)st.st_size);
}

static int dir_file_stats(struct object_directory *object_dir, void *data)
{
	struct strbuf *buf = data;

	strbuf_addf(buf, "Contents of %s:\n", object_dir->path);

	for_each_file_in_pack_dir(object_dir->path, dir_file_stats_objects,
				  data);

	return 0;
}

static int count_files(struct strbuf *path)
{
	DIR *dir = opendir(path->buf);
	struct dirent *e;
	int count = 0;

	if (!dir)
		return 0;

	while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL)
		if (get_dtype(e, path, 0) == DT_REG)
			count++;

	closedir(dir);
	return count;
}

static void loose_objs_stats(struct strbuf *buf, const char *path)
{
	DIR *dir = opendir(path);
	struct dirent *e;
	int count;
	int total = 0;
	unsigned char c;
	struct strbuf count_path = STRBUF_INIT;
	size_t base_path_len;

	if (!dir)
		return;

	strbuf_addstr(buf, "Object directory stats for ");
	strbuf_add_absolute_path(buf, path);
	strbuf_addstr(buf, ":\n");

	strbuf_add_absolute_path(&count_path, path);
	strbuf_addch(&count_path, '/');
	base_path_len = count_path.len;

	while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL)
		if (get_dtype(e, &count_path, 0) == DT_DIR &&
		    strlen(e->d_name) == 2 &&
		    !hex_to_bytes(&c, e->d_name, 1)) {
			strbuf_setlen(&count_path, base_path_len);
			strbuf_addf(&count_path, "%s/", e->d_name);
			total += (count = count_files(&count_path));
			strbuf_addf(buf, "%s : %7d files\n", e->d_name, count);
		}

	strbuf_addf(buf, "Total: %d loose objects", total);

	strbuf_release(&count_path);
	closedir(dir);
}

static int add_directory_to_archiver(struct strvec *archiver_args,
				     const char *path, int recurse)
{
	int at_root = !*path;
	DIR *dir;
	struct dirent *e;
	struct strbuf buf = STRBUF_INIT;
	size_t len;
	int res = 0;

	dir = opendir(at_root ? "." : path);
	if (!dir) {
		if (errno == ENOENT) {
			warning(_("could not archive missing directory '%s'"), path);
			return 0;
		}
		return error_errno(_("could not open directory '%s'"), path);
	}

	if (!at_root)
		strbuf_addf(&buf, "%s/", path);
	len = buf.len;
	strvec_pushf(archiver_args, "--prefix=%s", buf.buf);

	while (!res && (e = readdir_skip_dot_and_dotdot(dir))) {
		struct strbuf abspath = STRBUF_INIT;
		unsigned char dtype;

		strbuf_add_absolute_path(&abspath, at_root ? "." : path);
		strbuf_addch(&abspath, '/');
		dtype = get_dtype(e, &abspath, 0);

		strbuf_setlen(&buf, len);
		strbuf_addstr(&buf, e->d_name);

		if (dtype == DT_REG)
			strvec_pushf(archiver_args, "--add-file=%s", buf.buf);
		else if (dtype != DT_DIR)
			warning(_("skipping '%s', which is neither file nor "
				  "directory"), buf.buf);
		else if (recurse &&
			 add_directory_to_archiver(archiver_args,
						   buf.buf, recurse) < 0)
			res = -1;

		strbuf_release(&abspath);
	}

	closedir(dir);
	strbuf_release(&buf);
	return res;
}

int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode)
{
	struct strvec archiver_args = STRVEC_INIT;
	char **argv_copy = NULL;
	int stdout_fd = -1, archiver_fd = -1;
	struct strbuf buf = STRBUF_INIT;
	int res, i;
	struct archive_dir archive_dirs[] = {
		{ ".git", 0 },
		{ ".git/hooks", 0 },
		{ ".git/info", 0 },
		{ ".git/logs", 1 },
		{ ".git/objects/info", 0 }
	};

	if (mode == DIAGNOSE_NONE) {
		res = 0;
		goto diagnose_cleanup;
	}

	stdout_fd = dup(STDOUT_FILENO);
	if (stdout_fd < 0) {
		res = error_errno(_("could not duplicate stdout"));
		goto diagnose_cleanup;
	}

	archiver_fd = xopen(zip_path->buf, O_CREAT | O_WRONLY | O_TRUNC, 0666);
	if (dup2(archiver_fd, STDOUT_FILENO) < 0) {
		res = error_errno(_("could not redirect output"));
		goto diagnose_cleanup;
	}

	init_zip_archiver();
	strvec_pushl(&archiver_args, "git-diagnose", "--format=zip", NULL);

	strbuf_reset(&buf);
	strbuf_addstr(&buf, "Collecting diagnostic info\n\n");
	get_version_info(&buf, 1);

	strbuf_addf(&buf, "Repository root: %s\n", the_repository->worktree);
	get_disk_info(&buf);
	write_or_die(stdout_fd, buf.buf, buf.len);
	strvec_pushf(&archiver_args,
		     "--add-virtual-file=diagnostics.log:%.*s",
		     (int)buf.len, buf.buf);

	strbuf_reset(&buf);
	strbuf_addstr(&buf, "--add-virtual-file=packs-local.txt:");
	dir_file_stats(the_repository->objects->odb, &buf);
	foreach_alt_odb(dir_file_stats, &buf);
	strvec_push(&archiver_args, buf.buf);

	strbuf_reset(&buf);
	strbuf_addstr(&buf, "--add-virtual-file=objects-local.txt:");
	loose_objs_stats(&buf, ".git/objects");
	strvec_push(&archiver_args, buf.buf);

	/* Only include this if explicitly requested */
	if (mode == DIAGNOSE_ALL) {
		for (i = 0; i < ARRAY_SIZE(archive_dirs); i++) {
			if (add_directory_to_archiver(&archiver_args,
						      archive_dirs[i].path,
						      archive_dirs[i].recursive)) {
				res = error_errno(_("could not add directory '%s' to archiver"),
						  archive_dirs[i].path);
				goto diagnose_cleanup;
			}
		}
	}

	strvec_pushl(&archiver_args, "--prefix=",
		     oid_to_hex(the_hash_algo->empty_tree), "--", NULL);

	/* `write_archive()` modifies the `argv` passed to it. Let it. */
	argv_copy = xmemdupz(archiver_args.v,
			     sizeof(char *) * archiver_args.nr);
	res = write_archive(archiver_args.nr, (const char **)argv_copy, NULL,
			    the_repository, NULL, 0);
	if (res) {
		error(_("failed to write archive"));
		goto diagnose_cleanup;
	}

	fprintf(stderr, "\n"
		"Diagnostics complete.\n"
		"All of the gathered info is captured in '%s'\n",
		zip_path->buf);

diagnose_cleanup:
	if (archiver_fd >= 0) {
		dup2(stdout_fd, STDOUT_FILENO);
		close(stdout_fd);
		close(archiver_fd);
	}
	free(argv_copy);
	strvec_clear(&archiver_args);
	strbuf_release(&buf);

	return res;
}
