/*
 * The Scalar command-line interface.
 */

#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "abspath.h"
#include "gettext.h"
#include "parse-options.h"
#include "config.h"
#include "run-command.h"
#include "simple-ipc.h"
#include "fsmonitor-ipc.h"
#include "fsmonitor-settings.h"
#include "refs.h"
#include "dir.h"
#include "packfile.h"
#include "help.h"
#include "setup.h"
#include "trace2.h"
#include "path.h"

static void setup_enlistment_directory(int argc, const char **argv,
				       const char * const *usagestr,
				       const struct option *options,
				       struct strbuf *enlistment_root)
{
	struct strbuf path = STRBUF_INIT;
	int enlistment_is_repo_parent = 0;
	size_t len;

	if (startup_info->have_repository)
		BUG("gitdir already set up?!?");

	if (argc > 1)
		usage_with_options(usagestr, options);

	/* find the worktree, determine its corresponding root */
	if (argc == 1) {
		strbuf_add_absolute_path(&path, argv[0]);
		if (!is_directory(path.buf))
			die(_("'%s' does not exist"), path.buf);
		if (chdir(path.buf) < 0)
			die_errno(_("could not switch to '%s'"), path.buf);
	} else if (strbuf_getcwd(&path) < 0)
		die(_("need a working directory"));

	strbuf_trim_trailing_dir_sep(&path);

	/* check if currently in enlistment root with src/ workdir */
	len = path.len;
	strbuf_addstr(&path, "/src");
	if (is_nonbare_repository_dir(&path)) {
		enlistment_is_repo_parent = 1;
		if (chdir(path.buf) < 0)
			die_errno(_("could not switch to '%s'"), path.buf);
	}
	strbuf_setlen(&path, len);

	setup_git_directory(the_repository);

	if (!the_repository->worktree)
		die(_("Scalar enlistments require a worktree"));

	if (enlistment_root) {
		if (enlistment_is_repo_parent)
			strbuf_addbuf(enlistment_root, &path);
		else
			strbuf_addstr(enlistment_root, the_repository->worktree);
	}

	strbuf_release(&path);
}

LAST_ARG_MUST_BE_NULL
static int run_git(const char *arg, ...)
{
	struct child_process cmd = CHILD_PROCESS_INIT;
	va_list args;
	const char *p;

	va_start(args, arg);
	strvec_push(&cmd.args, arg);
	while ((p = va_arg(args, const char *)))
		strvec_push(&cmd.args, p);
	va_end(args);

	cmd.git_cmd = 1;
	return run_command(&cmd);
}

struct scalar_config {
	const char *key;
	const char *value;
	int overwrite_on_reconfigure;
};

static int set_scalar_config(const char *key, const char *value)
{
	char *file = repo_git_path(the_repository, "config");
	int res = repo_config_set_multivar_in_file_gently(the_repository, file,
							  key, value, NULL,
							  " # set by scalar", 0);
	free(file);
	return res;
}

static int set_config_if_missing(const struct scalar_config *config, int reconfigure)
{
	char *value = NULL;
	int res;

	if ((reconfigure && config->overwrite_on_reconfigure) ||
	    repo_config_get_string(the_repository, config->key, &value)) {
		trace2_data_string("scalar", the_repository, config->key, "created");
		res = set_scalar_config(config->key, config->value);
	} else {
		trace2_data_string("scalar", the_repository, config->key, "exists");
		res = 0;
	}

	free(value);
	return res;
}

static int have_fsmonitor_support(void)
{
	return fsmonitor_ipc__is_supported() &&
	       fsm_settings__get_reason(the_repository) == FSMONITOR_REASON_OK;
}

static int set_recommended_config(int reconfigure)
{
	/*
	 * Be sure to update Documentation/scalar.adoc if you add, update,
	 * or remove any of these recommended settings.
	 */
	struct scalar_config config[] = {
		{ "am.keepCR", "true" },
		{ "commitGraph.changedPaths", "true" },
		{ "commitGraph.generationVersion", "1" },
		{ "core.autoCRLF", "false" },
		{ "core.logAllRefUpdates", "true" },
		{ "core.safeCRLF", "false" },
		{ "credential.https://dev.azure.com.useHttpPath", "true" },
		{ "feature.experimental", "false" },
		{ "feature.manyFiles", "false" },
		{ "fetch.showForcedUpdates", "false" },
		{ "fetch.unpackLimit", "1" },
		{ "fetch.writeCommitGraph", "false" },
		{ "gc.auto", "0" },
		{ "gui.GCWarning", "false" },
		{ "index.skipHash", "true", 1 /* Fix previous setting. */ },
		{ "index.threads", "true"},
		{ "index.version", "4" },
		{ "merge.renames", "true" },
		{ "merge.stat", "false" },
		{ "pack.useBitmaps", "false" },
		{ "pack.usePathWalk", "true" },
		{ "receive.autoGC", "false" },
		{ "status.aheadBehind", "false" },

		/* platform-specific */
#ifndef WIN32
		{ "core.untrackedCache", "true" },
#else
		/*
		 * Unfortunately, Scalar's Functional Tests demonstrated
		 * that the untracked cache feature is unreliable on Windows
		 * (which is a bummer because that platform would benefit the
		 * most from it). For some reason, freshly created files seem
		 * not to update the directory's `lastModified` time
		 * immediately, but the untracked cache would need to rely on
		 * that.
		 *
		 * Therefore, with a sad heart, we disable this very useful
		 * feature on Windows.
		 */
		{ "core.untrackedCache", "false" },

		/* Other Windows-specific required settings: */
		{ "http.sslBackend", "schannel" },
#endif
		{ NULL, NULL },
	};
	int i;
	char *value;

	for (i = 0; config[i].key; i++) {
		if (set_config_if_missing(config + i, reconfigure))
			return error(_("could not configure %s=%s"),
				     config[i].key, config[i].value);
	}

	if (have_fsmonitor_support()) {
		struct scalar_config fsmonitor = { "core.fsmonitor", "true" };
		if (set_config_if_missing(&fsmonitor, reconfigure))
			return error(_("could not configure %s=%s"),
				     fsmonitor.key, fsmonitor.value);
	}

	/*
	 * The `log.excludeDecoration` setting is special because it allows
	 * for multiple values.
	 */
	if (repo_config_get_string(the_repository, "log.excludeDecoration", &value)) {
		trace2_data_string("scalar", the_repository,
				   "log.excludeDecoration", "created");
		if (set_scalar_config("log.excludeDecoration",
					    "refs/prefetch/*"))
			return error(_("could not configure "
				       "log.excludeDecoration"));
	} else {
		trace2_data_string("scalar", the_repository,
				   "log.excludeDecoration", "exists");
		free(value);
	}

	return 0;
}

/**
 * Enable or disable the maintenance mode for the current repository:
 *
 * * If 'enable' is nonzero, run 'git maintenance start'.
 * * If 'enable' is zero, run 'git maintenance unregister --force'.
 */
static int toggle_maintenance(int enable)
{
	return run_git("maintenance",
		       enable ? "start" : "unregister",
		       enable ? NULL : "--force",
		       NULL);
}

static int add_or_remove_enlistment(int add)
{
	int res;

	if (!the_repository->worktree)
		die(_("Scalar enlistments require a worktree"));

	res = run_git("config", "--global", "--get", "--fixed-value",
		      "scalar.repo", the_repository->worktree, NULL);

	/*
	 * If we want to add and the setting is already there, then do nothing.
	 * If we want to remove and the setting is not there, then do nothing.
	 */
	if ((add && !res) || (!add && res))
		return 0;

	return run_git("config", "--global", add ? "--add" : "--unset",
		       add ? "--no-fixed-value" : "--fixed-value",
		       "scalar.repo", the_repository->worktree, NULL);
}

static int start_fsmonitor_daemon(void)
{
	ASSERT(have_fsmonitor_support());

	if (fsmonitor_ipc__get_state() != IPC_STATE__LISTENING)
		return run_git("fsmonitor--daemon", "start", NULL);

	return 0;
}

static int stop_fsmonitor_daemon(void)
{
	ASSERT(have_fsmonitor_support());

	if (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
		return run_git("fsmonitor--daemon", "stop", NULL);

	return 0;
}

/**
 * Register the current directory as a Scalar enlistment, and set the
 * recommended configuration.
 *
 * * If 'maintenance' is non-zero, then enable background maintenance.
 * * If 'maintenance' is zero, then leave background maintenance as it is
 *   currently configured.
 */
static int register_dir(int maintenance)
{
	if (add_or_remove_enlistment(1))
		return error(_("could not add enlistment"));

	if (set_recommended_config(0))
		return error(_("could not set recommended config"));

	if (maintenance &&
	    toggle_maintenance(maintenance))
		warning(_("could not toggle maintenance"));

	if (have_fsmonitor_support() && start_fsmonitor_daemon()) {
		return error(_("could not start the FSMonitor daemon"));
	}

	return 0;
}

static int unregister_dir(void)
{
	int res = 0;

	if (toggle_maintenance(0))
		res = error(_("could not turn off maintenance"));

	if (add_or_remove_enlistment(0))
		res = error(_("could not remove enlistment"));

	return res;
}

/* printf-style interface, expects `<key>=<value>` argument */
__attribute__((format (printf, 1, 2)))
static int set_config(const char *fmt, ...)
{
	struct strbuf buf = STRBUF_INIT;
	char *value;
	int res;
	va_list args;

	va_start(args, fmt);
	strbuf_vaddf(&buf, fmt, args);
	va_end(args);

	value = strchr(buf.buf, '=');
	if (value)
		*(value++) = '\0';
	res = repo_config_set_gently(the_repository, buf.buf, value);
	strbuf_release(&buf);

	return res;
}

static char *remote_default_branch(const char *url)
{
	struct child_process cp = CHILD_PROCESS_INIT;
	struct strbuf out = STRBUF_INIT;

	cp.git_cmd = 1;
	strvec_pushl(&cp.args, "ls-remote", "--symref", url, "HEAD", NULL);
	if (!pipe_command(&cp, NULL, 0, &out, 0, NULL, 0)) {
		const char *line = out.buf;

		while (*line) {
			const char *eol = strchrnul(line, '\n'), *p;
			size_t len = eol - line;
			char *branch;

			if (!skip_prefix(line, "ref: ", &p) ||
			    !strip_suffix_mem(line, &len, "\tHEAD")) {
				line = eol + (*eol == '\n');
				continue;
			}

			eol = line + len;
			if (skip_prefix(p, "refs/heads/", &p)) {
				branch = xstrndup(p, eol - p);
				strbuf_release(&out);
				return branch;
			}

			error(_("remote HEAD is not a branch: '%.*s'"),
			      (int)(eol - p), p);
			strbuf_release(&out);
			return NULL;
		}
	}
	warning(_("failed to get default branch name from remote; "
		  "using local default"));
	strbuf_reset(&out);

	child_process_init(&cp);
	cp.git_cmd = 1;
	strvec_pushl(&cp.args, "symbolic-ref", "--short", "HEAD", NULL);
	if (!pipe_command(&cp, NULL, 0, &out, 0, NULL, 0)) {
		strbuf_trim(&out);
		return strbuf_detach(&out, NULL);
	}

	strbuf_release(&out);
	error(_("failed to get default branch name"));
	return NULL;
}

static int delete_enlistment(struct strbuf *enlistment)
{
	struct strbuf parent = STRBUF_INIT;
	size_t offset;
	const char *path_sep;

	if (unregister_dir())
		return error(_("failed to unregister repository"));

	/*
	 * Change the current directory to one outside of the enlistment so
	 * that we may delete everything underneath it.
	 */
	offset = offset_1st_component(enlistment->buf);
	path_sep = find_last_dir_sep(enlistment->buf + offset);
	strbuf_add(&parent, enlistment->buf,
		   path_sep ? (size_t) (path_sep - enlistment->buf) : offset);
	if (chdir(parent.buf) < 0) {
		int res = error_errno(_("could not switch to '%s'"), parent.buf);
		strbuf_release(&parent);
		return res;
	}
	strbuf_release(&parent);

	if (have_fsmonitor_support() && stop_fsmonitor_daemon())
		return error(_("failed to stop the FSMonitor daemon"));

	if (remove_dir_recursively(enlistment, 0))
		return error(_("failed to delete enlistment directory"));

	return 0;
}

/*
 * Dummy implementation; Using `get_version_info()` would cause a link error
 * without this.
 */
void load_builtin_commands(const char *prefix UNUSED,
			   struct cmdnames *cmds UNUSED)
{
	die("not implemented");
}

static int cmd_clone(int argc, const char **argv)
{
	const char *branch = NULL;
	char *branch_to_free = NULL;
	int full_clone = 0, single_branch = 0, show_progress = isatty(2);
	int src = 1, tags = 1, maintenance = 1;
	struct option clone_options[] = {
		OPT_STRING('b', "branch", &branch, N_("<branch>"),
			   N_("branch to checkout after clone")),
		OPT_BOOL(0, "full-clone", &full_clone,
			 N_("when cloning, create full working directory")),
		OPT_BOOL(0, "single-branch", &single_branch,
			 N_("only download metadata for the branch that will "
			    "be checked out")),
		OPT_BOOL(0, "src", &src,
			 N_("create repository within 'src' directory")),
		OPT_BOOL(0, "tags", &tags,
			 N_("specify if tags should be fetched during clone")),
		OPT_BOOL(0, "maintenance", &maintenance,
			 N_("specify if background maintenance should be enabled")),
		OPT_END(),
	};
	const char * const clone_usage[] = {
		N_("scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n"
		   "\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] <url> [<enlistment>]"),
		NULL
	};
	const char *url;
	char *enlistment = NULL, *dir = NULL;
	struct strbuf buf = STRBUF_INIT;
	int res;

	argc = parse_options(argc, argv, NULL, clone_options, clone_usage, 0);

	if (argc == 2) {
		url = argv[0];
		enlistment = xstrdup(argv[1]);
	} else if (argc == 1) {
		url = argv[0];

		strbuf_addstr(&buf, url);
		/* Strip trailing slashes, if any */
		while (buf.len > 0 && is_dir_sep(buf.buf[buf.len - 1]))
			strbuf_setlen(&buf, buf.len - 1);
		/* Strip suffix `.git`, if any */
		strbuf_strip_suffix(&buf, ".git");

		enlistment = find_last_dir_sep(buf.buf);
		if (!enlistment) {
			die(_("cannot deduce worktree name from '%s'"), url);
		}
		enlistment = xstrdup(enlistment + 1);
	} else {
		usage_msg_opt(_("You must specify a repository to clone."),
			      clone_usage, clone_options);
	}

	if (is_directory(enlistment))
		die(_("directory '%s' exists already"), enlistment);

	if (src)
		dir = xstrfmt("%s/src", enlistment);
	else
		dir = xstrdup(enlistment);

	strbuf_reset(&buf);
	if (branch)
		strbuf_addf(&buf, "init.defaultBranch=%s", branch);
	else {
		char *b = repo_default_branch_name(the_repository, 1);
		strbuf_addf(&buf, "init.defaultBranch=%s", b);
		free(b);
	}

	if ((res = run_git("-c", buf.buf, "init", "--", dir, NULL)))
		goto cleanup;

	if (chdir(dir) < 0) {
		res = error_errno(_("could not switch to '%s'"), dir);
		goto cleanup;
	}

	setup_git_directory(the_repository);

	/* common-main already logs `argv` */
	trace2_def_repo(the_repository);

	if (!branch && !(branch = branch_to_free = remote_default_branch(url))) {
		res = error(_("failed to get default branch for '%s'"), url);
		goto cleanup;
	}

	if (set_config("remote.origin.url=%s", url) ||
	    set_config("remote.origin.fetch="
		       "+refs/heads/%s:refs/remotes/origin/%s",
		       single_branch ? branch : "*",
		       single_branch ? branch : "*") ||
	    set_config("remote.origin.promisor=true") ||
	    set_config("remote.origin.partialCloneFilter=blob:none")) {
		res = error(_("could not configure remote in '%s'"), dir);
		goto cleanup;
	}

	if (!tags && set_config("remote.origin.tagOpt=--no-tags")) {
		res = error(_("could not disable tags in '%s'"), dir);
		goto cleanup;
	}

	if (!full_clone &&
	    (res = run_git("sparse-checkout", "init", "--cone", NULL)))
		goto cleanup;

	if (set_recommended_config(0))
		return error(_("could not configure '%s'"), dir);

	if ((res = run_git("fetch", "--quiet",
				show_progress ? "--progress" : "--no-progress",
				"origin",
				(tags ? NULL : "--no-tags"),
				NULL))) {
		warning(_("partial clone failed; attempting full clone"));

		if (set_config("remote.origin.promisor") ||
		    set_config("remote.origin.partialCloneFilter")) {
			res = error(_("could not configure for full clone"));
			goto cleanup;
		}

		if ((res = run_git("fetch", "--quiet",
					show_progress ? "--progress" : "--no-progress",
					"origin", NULL)))
			goto cleanup;
	}

	if ((res = set_config("branch.%s.remote=origin", branch)))
		goto cleanup;
	if ((res = set_config("branch.%s.merge=refs/heads/%s",
			      branch, branch)))
		goto cleanup;

	strbuf_reset(&buf);
	strbuf_addf(&buf, "origin/%s", branch);
	res = run_git("checkout", "-f", "-t", buf.buf, NULL);
	if (res)
		goto cleanup;

	/* If --no-maintenance, then skip maintenance command entirely. */
	res = register_dir(maintenance);

cleanup:
	free(branch_to_free);
	free(enlistment);
	free(dir);
	strbuf_release(&buf);
	return res;
}

static int cmd_diagnose(int argc, const char **argv)
{
	struct option options[] = {
		OPT_END(),
	};
	const char * const usage[] = {
		N_("scalar diagnose [<enlistment>]"),
		NULL
	};
	struct strbuf diagnostics_root = STRBUF_INIT;
	int res = 0;

	argc = parse_options(argc, argv, NULL, options,
			     usage, 0);

	setup_enlistment_directory(argc, argv, usage, options, &diagnostics_root);
	strbuf_addstr(&diagnostics_root, "/.scalarDiagnostics");

	res = run_git("diagnose", "--mode=all", "-s", "%Y%m%d_%H%M%S",
		      "-o", diagnostics_root.buf, NULL);

	strbuf_release(&diagnostics_root);
	return res;
}

static int cmd_list(int argc, const char **argv UNUSED)
{
	if (argc != 1)
		die(_("`scalar list` does not take arguments"));

	if (run_git("config", "--global", "--get-all", "scalar.repo", NULL) < 0)
		return -1;
	return 0;
}

static int cmd_register(int argc, const char **argv)
{
	int maintenance = 1;
	struct option options[] = {
		OPT_BOOL(0, "maintenance", &maintenance,
			 N_("specify if background maintenance should be enabled")),
		OPT_END(),
	};
	const char * const usage[] = {
		N_("scalar register [--[no-]maintenance] [<enlistment>]"),
		NULL
	};

	argc = parse_options(argc, argv, NULL, options,
			     usage, 0);

	setup_enlistment_directory(argc, argv, usage, options, NULL);

	/* If --no-maintenance, then leave maintenance as-is. */
	return register_dir(maintenance);
}

static int get_scalar_repos(const char *key, const char *value,
			    const struct config_context *ctx UNUSED,
			    void *data)
{
	struct string_list *list = data;

	if (!strcmp(key, "scalar.repo"))
		string_list_append(list, value);

	return 0;
}

static int remove_deleted_enlistment(struct strbuf *path)
{
	int res = 0;
	strbuf_realpath_forgiving(path, path->buf, 1);

	if (run_git("config", "--global",
		    "--unset", "--fixed-value",
		    "scalar.repo", path->buf, NULL) < 0)
		res = -1;

	if (run_git("config", "--global",
		    "--unset", "--fixed-value",
		    "maintenance.repo", path->buf, NULL) < 0)
		res = -1;

	return res;
}

static int cmd_reconfigure(int argc, const char **argv)
{
	int all = 0;
	const char *maintenance_str = NULL;
	int maintenance = 1; /* Enable maintenance by default. */

	struct option options[] = {
		OPT_BOOL('a', "all", &all,
			 N_("reconfigure all registered enlistments")),
		OPT_STRING(0, "maintenance", &maintenance_str,
			 N_("(enable|disable|keep)"),
			 N_("signal how to adjust background maintenance")),
		OPT_END(),
	};
	const char * const usage[] = {
		N_("scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | <enlistment>]"),
		NULL
	};
	struct string_list scalar_repos = STRING_LIST_INIT_DUP;
	int res = 0;
	struct strbuf commondir = STRBUF_INIT, gitdir = STRBUF_INIT;

	argc = parse_options(argc, argv, NULL, options,
			     usage, 0);

	if (!all) {
		setup_enlistment_directory(argc, argv, usage, options, NULL);

		return set_recommended_config(1);
	}

	if (argc > 0)
		usage_msg_opt(_("--all or <enlistment>, but not both"),
			      usage, options);

	if (maintenance_str) {
		if (!strcmp(maintenance_str, "enable"))
			maintenance = 1;
		else if (!strcmp(maintenance_str, "disable"))
			maintenance = 0;
		else if (!strcmp(maintenance_str, "keep"))
			maintenance = -1;
		else
			die(_("unknown mode for --maintenance option: %s"),
			    maintenance_str);
	}

	repo_config(the_repository, get_scalar_repos, &scalar_repos);

	for (size_t i = 0; i < scalar_repos.nr; i++) {
		int succeeded = 0;
		struct repository *old_repo, r = { NULL };
		const char *dir = scalar_repos.items[i].string;

		strbuf_reset(&commondir);
		strbuf_reset(&gitdir);

		if (chdir(dir) < 0) {
			struct strbuf buf = STRBUF_INIT;

			if (errno != ENOENT) {
				warning_errno(_("could not switch to '%s'"), dir);
				goto loop_end;
			}

			strbuf_addstr(&buf, dir);
			if (remove_deleted_enlistment(&buf))
				error(_("could not remove stale "
					"scalar.repo '%s'"), dir);
			else {
				warning(_("removed stale scalar.repo '%s'"),
					dir);
				succeeded = 1;
			}
			strbuf_release(&buf);
			goto loop_end;
		}

		switch (discover_git_directory_reason(&commondir, &gitdir)) {
		case GIT_DIR_INVALID_OWNERSHIP:
			warning(_("repository at '%s' has different owner"), dir);
			goto loop_end;

		case GIT_DIR_INVALID_GITFILE:
		case GIT_DIR_INVALID_FORMAT:
			warning(_("repository at '%s' has a format issue"), dir);
			goto loop_end;

		case GIT_DIR_DISCOVERED:
			succeeded = 1;
			break;

		default:
			warning(_("repository not found in '%s'"), dir);
			break;
		}

		repo_config_clear(the_repository);

		if (repo_init(&r, gitdir.buf, commondir.buf))
			goto loop_end;

		old_repo = the_repository;
		the_repository = &r;

		if (set_recommended_config(1) >= 0)
			succeeded = 1;

		the_repository = old_repo;
		repo_clear(&r);

		if (maintenance >= 0 &&
		    toggle_maintenance(maintenance) >= 0)
			succeeded = 1;

loop_end:
		if (!succeeded) {
			res = -1;
			warning(_("to unregister this repository from Scalar, run\n"
				  "\tgit config --global --unset --fixed-value scalar.repo \"%s\""),
				dir);
		}
	}

	string_list_clear(&scalar_repos, 1);
	strbuf_release(&commondir);
	strbuf_release(&gitdir);

	return res;
}

static int cmd_run(int argc, const char **argv)
{
	struct option options[] = {
		OPT_END(),
	};
	struct {
		const char *arg, *task;
	} tasks[] = {
		{ "config", NULL },
		{ "commit-graph", "commit-graph" },
		{ "fetch", "prefetch" },
		{ "loose-objects", "loose-objects" },
		{ "pack-files", "incremental-repack" },
		{ NULL, NULL }
	};
	struct strbuf buf = STRBUF_INIT;
	const char *usagestr[] = { NULL, NULL };
	int i;

	strbuf_addstr(&buf, N_("scalar run <task> [<enlistment>]\nTasks:\n"));
	for (i = 0; tasks[i].arg; i++)
		strbuf_addf(&buf, "\t%s\n", tasks[i].arg);
	usagestr[0] = buf.buf;

	argc = parse_options(argc, argv, NULL, options,
			     usagestr, 0);

	if (!argc)
		usage_with_options(usagestr, options);

	if (!strcmp("all", argv[0])) {
		i = -1;
	} else {
		for (i = 0; tasks[i].arg && strcmp(tasks[i].arg, argv[0]); i++)
			; /* keep looking for the task */

		if (i > 0 && !tasks[i].arg) {
			error(_("no such task: '%s'"), argv[0]);
			usage_with_options(usagestr, options);
		}
	}

	argc--;
	argv++;
	setup_enlistment_directory(argc, argv, usagestr, options, NULL);
	strbuf_release(&buf);

	if (i == 0)
		return register_dir(1);

	if (i > 0)
		return run_git("maintenance", "run",
			       "--task", tasks[i].task, NULL);

	if (register_dir(1))
		return -1;
	for (i = 1; tasks[i].arg; i++)
		if (run_git("maintenance", "run",
			    "--task", tasks[i].task, NULL))
			return -1;
	return 0;
}

static int cmd_unregister(int argc, const char **argv)
{
	struct option options[] = {
		OPT_END(),
	};
	const char * const usage[] = {
		N_("scalar unregister [<enlistment>]"),
		NULL
	};

	argc = parse_options(argc, argv, NULL, options,
			     usage, 0);

	/*
	 * Be forgiving when the enlistment or worktree does not even exist any
	 * longer; This can be the case if a user deleted the worktree by
	 * mistake and _still_ wants to unregister the thing.
	 */
	if (argc == 1) {
		struct strbuf src_path = STRBUF_INIT, workdir_path = STRBUF_INIT;

		strbuf_addf(&src_path, "%s/src/.git", argv[0]);
		strbuf_addf(&workdir_path, "%s/.git", argv[0]);
		if (!is_directory(src_path.buf) && !is_directory(workdir_path.buf)) {
			/* remove possible matching registrations */
			int res = -1;

			strbuf_strip_suffix(&src_path, "/.git");
			res = remove_deleted_enlistment(&src_path) && res;

			strbuf_strip_suffix(&workdir_path, "/.git");
			res = remove_deleted_enlistment(&workdir_path) && res;

			strbuf_release(&src_path);
			strbuf_release(&workdir_path);
			return res;
		}
		strbuf_release(&src_path);
		strbuf_release(&workdir_path);
	}

	setup_enlistment_directory(argc, argv, usage, options, NULL);

	return unregister_dir();
}

static int cmd_delete(int argc, const char **argv)
{
	char *cwd = xgetcwd();
	struct option options[] = {
		OPT_END(),
	};
	const char * const usage[] = {
		N_("scalar delete <enlistment>"),
		NULL
	};
	struct strbuf enlistment = STRBUF_INIT;
	int res = 0;

	argc = parse_options(argc, argv, NULL, options,
			     usage, 0);

	if (argc != 1)
		usage_with_options(usage, options);

	setup_enlistment_directory(argc, argv, usage, options, &enlistment);

	if (dir_inside_of(cwd, enlistment.buf) >= 0)
		res = error(_("refusing to delete current working directory"));
	else {
		odb_close(the_repository->objects);
		res = delete_enlistment(&enlistment);
	}
	strbuf_release(&enlistment);
	free(cwd);

	return res;
}

static int cmd_help(int argc, const char **argv)
{
	struct option options[] = {
		OPT_END(),
	};
	const char * const usage[] = {
		"scalar help",
		NULL
	};

	argc = parse_options(argc, argv, NULL, options,
			     usage, 0);

	if (argc != 0)
		usage_with_options(usage, options);

	return run_git("help", "scalar", NULL);
}

static int cmd_version(int argc, const char **argv)
{
	int verbose = 0, build_options = 0;
	struct option options[] = {
		OPT__VERBOSE(&verbose, N_("include Git version")),
		OPT_BOOL(0, "build-options", &build_options,
			 N_("include Git's build options")),
		OPT_END(),
	};
	const char * const usage[] = {
		N_("scalar verbose [-v | --verbose] [--build-options]"),
		NULL
	};
	struct strbuf buf = STRBUF_INIT;

	argc = parse_options(argc, argv, NULL, options,
			     usage, 0);

	if (argc != 0)
		usage_with_options(usage, options);

	get_version_info(&buf, build_options);
	fprintf(stderr, "%s\n", buf.buf);
	strbuf_release(&buf);

	return 0;
}

static struct {
	const char *name;
	int (*fn)(int, const char **);
} builtins[] = {
	{ "clone", cmd_clone },
	{ "list", cmd_list },
	{ "register", cmd_register },
	{ "unregister", cmd_unregister },
	{ "run", cmd_run },
	{ "reconfigure", cmd_reconfigure },
	{ "delete", cmd_delete },
	{ "help", cmd_help },
	{ "version", cmd_version },
	{ "diagnose", cmd_diagnose },
	{ NULL, NULL},
};

int cmd_main(int argc, const char **argv)
{
	struct strbuf scalar_usage = STRBUF_INIT;
	int i;

	while (argc > 1 && *argv[1] == '-') {
		if (!strcmp(argv[1], "-C")) {
			if (argc < 3)
				die(_("-C requires a <directory>"));
			if (chdir(argv[2]) < 0)
				die_errno(_("could not change to '%s'"),
					  argv[2]);
			argc -= 2;
			argv += 2;
		} else if (!strcmp(argv[1], "-c")) {
			if (argc < 3)
				die(_("-c requires a <key>=<value> argument"));
			git_config_push_parameter(argv[2]);
			argc -= 2;
			argv += 2;
		} else
			break;
	}

	if (argc > 1) {
		argv++;
		argc--;

		for (i = 0; builtins[i].name; i++)
			if (!strcmp(builtins[i].name, argv[0]))
				return !!builtins[i].fn(argc, argv);
	}

	strbuf_addstr(&scalar_usage,
		      N_("scalar [-C <directory>] [-c <key>=<value>] "
			 "<command> [<options>]\n\nCommands:\n"));
	for (i = 0; builtins[i].name; i++)
		strbuf_addf(&scalar_usage, "\t%s\n", builtins[i].name);

	usage(scalar_usage.buf);
}
