#include "git-compat-util.h"
#include "bundle-uri.h"
#include "bundle.h"
#include "copy.h"
#include "environment.h"
#include "gettext.h"
#include "object-store.h"
#include "refs.h"
#include "run-command.h"
#include "hashmap.h"
#include "pkt-line.h"
#include "config.h"
#include "remote.h"

static struct {
	enum bundle_list_heuristic heuristic;
	const char *name;
} heuristics[BUNDLE_HEURISTIC__COUNT] = {
	{ BUNDLE_HEURISTIC_NONE, ""},
	{ BUNDLE_HEURISTIC_CREATIONTOKEN, "creationToken" },
};

static int compare_bundles(const void *hashmap_cmp_fn_data,
			   const struct hashmap_entry *he1,
			   const struct hashmap_entry *he2,
			   const void *id)
{
	const struct remote_bundle_info *e1 =
		container_of(he1, const struct remote_bundle_info, ent);
	const struct remote_bundle_info *e2 =
		container_of(he2, const struct remote_bundle_info, ent);

	return strcmp(e1->id, id ? (const char *)id : e2->id);
}

void init_bundle_list(struct bundle_list *list)
{
	memset(list, 0, sizeof(*list));

	/* Implied defaults. */
	list->mode = BUNDLE_MODE_ALL;
	list->version = 1;

	hashmap_init(&list->bundles, compare_bundles, NULL, 0);
}

static int clear_remote_bundle_info(struct remote_bundle_info *bundle,
				    void *data)
{
	FREE_AND_NULL(bundle->id);
	FREE_AND_NULL(bundle->uri);
	FREE_AND_NULL(bundle->file);
	bundle->unbundled = 0;
	return 0;
}

void clear_bundle_list(struct bundle_list *list)
{
	if (!list)
		return;

	for_all_bundles_in_list(list, clear_remote_bundle_info, NULL);
	hashmap_clear_and_free(&list->bundles, struct remote_bundle_info, ent);
	free(list->baseURI);
}

int for_all_bundles_in_list(struct bundle_list *list,
			    bundle_iterator iter,
			    void *data)
{
	struct remote_bundle_info *info;
	struct hashmap_iter i;

	hashmap_for_each_entry(&list->bundles, &i, info, ent) {
		int result = iter(info, data);

		if (result)
			return result;
	}

	return 0;
}

static int summarize_bundle(struct remote_bundle_info *info, void *data)
{
	FILE *fp = data;
	fprintf(fp, "[bundle \"%s\"]\n", info->id);
	fprintf(fp, "\turi = %s\n", info->uri);

	if (info->creationToken)
		fprintf(fp, "\tcreationToken = %"PRIu64"\n", info->creationToken);
	return 0;
}

void print_bundle_list(FILE *fp, struct bundle_list *list)
{
	const char *mode;

	switch (list->mode) {
	case BUNDLE_MODE_ALL:
		mode = "all";
		break;

	case BUNDLE_MODE_ANY:
		mode = "any";
		break;

	case BUNDLE_MODE_NONE:
	default:
		mode = "<unknown>";
	}

	fprintf(fp, "[bundle]\n");
	fprintf(fp, "\tversion = %d\n", list->version);
	fprintf(fp, "\tmode = %s\n", mode);

	if (list->heuristic) {
		int i;
		for (i = 0; i < BUNDLE_HEURISTIC__COUNT; i++) {
			if (heuristics[i].heuristic == list->heuristic) {
				printf("\theuristic = %s\n",
				       heuristics[list->heuristic].name);
				break;
			}
		}
	}

	for_all_bundles_in_list(list, summarize_bundle, fp);
}

/**
 * Given a key-value pair, update the state of the given bundle list.
 * Returns 0 if the key-value pair is understood. Returns -1 if the key
 * is not understood or the value is malformed.
 */
static int bundle_list_update(const char *key, const char *value,
			      struct bundle_list *list)
{
	struct strbuf id = STRBUF_INIT;
	struct remote_bundle_info lookup = REMOTE_BUNDLE_INFO_INIT;
	struct remote_bundle_info *bundle;
	const char *subsection, *subkey;
	size_t subsection_len;

	if (parse_config_key(key, "bundle", &subsection, &subsection_len, &subkey))
		return -1;

	if (!subsection_len) {
		if (!strcmp(subkey, "version")) {
			int version;
			if (!git_parse_int(value, &version))
				return -1;
			if (version != 1)
				return -1;

			list->version = version;
			return 0;
		}

		if (!strcmp(subkey, "mode")) {
			if (!strcmp(value, "all"))
				list->mode = BUNDLE_MODE_ALL;
			else if (!strcmp(value, "any"))
				list->mode = BUNDLE_MODE_ANY;
			else
				return -1;
			return 0;
		}

		if (!strcmp(subkey, "heuristic")) {
			int i;
			for (i = 0; i < BUNDLE_HEURISTIC__COUNT; i++) {
				if (heuristics[i].heuristic &&
				    heuristics[i].name &&
				    !strcmp(value, heuristics[i].name)) {
					list->heuristic = heuristics[i].heuristic;
					return 0;
				}
			}

			/* Ignore unknown heuristics. */
			return 0;
		}

		/* Ignore other unknown global keys. */
		return 0;
	}

	strbuf_add(&id, subsection, subsection_len);

	/*
	 * Check for an existing bundle with this <id>, or create one
	 * if necessary.
	 */
	lookup.id = id.buf;
	hashmap_entry_init(&lookup.ent, strhash(lookup.id));
	if (!(bundle = hashmap_get_entry(&list->bundles, &lookup, ent, NULL))) {
		CALLOC_ARRAY(bundle, 1);
		bundle->id = strbuf_detach(&id, NULL);
		hashmap_entry_init(&bundle->ent, strhash(bundle->id));
		hashmap_add(&list->bundles, &bundle->ent);
	}
	strbuf_release(&id);

	if (!strcmp(subkey, "uri")) {
		if (bundle->uri)
			return -1;
		bundle->uri = relative_url(list->baseURI, value, NULL);
		return 0;
	}

	if (!strcmp(subkey, "creationtoken")) {
		if (sscanf(value, "%"PRIu64, &bundle->creationToken) != 1)
			warning(_("could not parse bundle list key %s with value '%s'"),
				"creationToken", value);
		return 0;
	}

	/*
	 * At this point, we ignore any information that we don't
	 * understand, assuming it to be hints for a heuristic the client
	 * does not currently understand.
	 */
	return 0;
}

static int config_to_bundle_list(const char *key, const char *value, void *data)
{
	struct bundle_list *list = data;
	return bundle_list_update(key, value, list);
}

int bundle_uri_parse_config_format(const char *uri,
				   const char *filename,
				   struct bundle_list *list)
{
	int result;
	struct config_options opts = {
		.error_action = CONFIG_ERROR_ERROR,
	};

	if (!list->baseURI) {
		struct strbuf baseURI = STRBUF_INIT;
		strbuf_addstr(&baseURI, uri);

		/*
		 * If the URI does not end with a trailing slash, then
		 * remove the filename portion of the path. This is
		 * important for relative URIs.
		 */
		strbuf_strip_file_from_path(&baseURI);
		list->baseURI = strbuf_detach(&baseURI, NULL);
	}
	result = git_config_from_file_with_options(config_to_bundle_list,
						   filename, list,
						   &opts);

	if (!result && list->mode == BUNDLE_MODE_NONE) {
		warning(_("bundle list at '%s' has no mode"), uri);
		result = 1;
	}

	return result;
}

static char *find_temp_filename(void)
{
	int fd;
	struct strbuf name = STRBUF_INIT;
	/*
	 * Find a temporary filename that is available. This is briefly
	 * racy, but unlikely to collide.
	 */
	fd = odb_mkstemp(&name, "bundles/tmp_uri_XXXXXX");
	if (fd < 0) {
		warning(_("failed to create temporary file"));
		return NULL;
	}

	close(fd);
	unlink(name.buf);
	return strbuf_detach(&name, NULL);
}

static int download_https_uri_to_file(const char *file, const char *uri)
{
	int result = 0;
	struct child_process cp = CHILD_PROCESS_INIT;
	FILE *child_in = NULL, *child_out = NULL;
	struct strbuf line = STRBUF_INIT;
	int found_get = 0;

	strvec_pushl(&cp.args, "git-remote-https", uri, NULL);
	cp.err = -1;
	cp.in = -1;
	cp.out = -1;

	if (start_command(&cp))
		return 1;

	child_in = fdopen(cp.in, "w");
	if (!child_in) {
		result = 1;
		goto cleanup;
	}

	child_out = fdopen(cp.out, "r");
	if (!child_out) {
		result = 1;
		goto cleanup;
	}

	fprintf(child_in, "capabilities\n");
	fflush(child_in);

	while (!strbuf_getline(&line, child_out)) {
		if (!line.len)
			break;
		if (!strcmp(line.buf, "get"))
			found_get = 1;
	}
	strbuf_release(&line);

	if (!found_get) {
		result = error(_("insufficient capabilities"));
		goto cleanup;
	}

	fprintf(child_in, "get %s %s\n\n", uri, file);

cleanup:
	if (child_in)
		fclose(child_in);
	if (finish_command(&cp))
		return 1;
	if (child_out)
		fclose(child_out);
	return result;
}

static int copy_uri_to_file(const char *filename, const char *uri)
{
	const char *out;

	if (starts_with(uri, "https:") ||
	    starts_with(uri, "http:"))
		return download_https_uri_to_file(filename, uri);

	if (skip_prefix(uri, "file://", &out))
		uri = out;

	/* Copy as a file */
	return copy_file(filename, uri, 0);
}

static int unbundle_from_file(struct repository *r, const char *file)
{
	int result = 0;
	int bundle_fd;
	struct bundle_header header = BUNDLE_HEADER_INIT;
	struct string_list_item *refname;
	struct strbuf bundle_ref = STRBUF_INIT;
	size_t bundle_prefix_len;

	if ((bundle_fd = read_bundle_header(file, &header)) < 0)
		return 1;

	/*
	 * Skip the reachability walk here, since we will be adding
	 * a reachable ref pointing to the new tips, which will reach
	 * the prerequisite commits.
	 */
	if ((result = unbundle(r, &header, bundle_fd, NULL,
			       VERIFY_BUNDLE_QUIET)))
		return 1;

	/*
	 * Convert all refs/heads/ from the bundle into refs/bundles/
	 * in the local repository.
	 */
	strbuf_addstr(&bundle_ref, "refs/bundles/");
	bundle_prefix_len = bundle_ref.len;

	for_each_string_list_item(refname, &header.references) {
		struct object_id *oid = refname->util;
		struct object_id old_oid;
		const char *branch_name;
		int has_old;

		if (!skip_prefix(refname->string, "refs/heads/", &branch_name))
			continue;

		strbuf_setlen(&bundle_ref, bundle_prefix_len);
		strbuf_addstr(&bundle_ref, branch_name);

		has_old = !read_ref(bundle_ref.buf, &old_oid);
		update_ref("fetched bundle", bundle_ref.buf, oid,
			   has_old ? &old_oid : NULL,
			   REF_SKIP_OID_VERIFICATION,
			   UPDATE_REFS_MSG_ON_ERR);
	}

	bundle_header_release(&header);
	return result;
}

struct bundle_list_context {
	struct repository *r;
	struct bundle_list *list;
	enum bundle_list_mode mode;
	int count;
	int depth;
};

/*
 * This early definition is necessary because we use indirect recursion:
 *
 * While iterating through a bundle list that was downloaded as part
 * of fetch_bundle_uri_internal(), iterator methods eventually call it
 * again, but with depth + 1.
 */
static int fetch_bundle_uri_internal(struct repository *r,
				     struct remote_bundle_info *bundle,
				     int depth,
				     struct bundle_list *list);

static int download_bundle_to_file(struct remote_bundle_info *bundle, void *data)
{
	int res;
	struct bundle_list_context *ctx = data;

	if (ctx->mode == BUNDLE_MODE_ANY && ctx->count)
		return 0;

	res = fetch_bundle_uri_internal(ctx->r, bundle, ctx->depth + 1, ctx->list);

	/*
	 * Only increment count if the download succeeded. If our mode is
	 * BUNDLE_MODE_ANY, then we will want to try other URIs in the
	 * list in case they work instead.
	 */
	if (!res)
		ctx->count++;

	/*
	 * To be opportunistic as possible, we continue iterating and
	 * download as many bundles as we can, so we can apply the ones
	 * that work, even in BUNDLE_MODE_ALL mode.
	 */
	return 0;
}

struct bundles_for_sorting {
	struct remote_bundle_info **items;
	size_t alloc;
	size_t nr;
};

static int append_bundle(struct remote_bundle_info *bundle, void *data)
{
	struct bundles_for_sorting *list = data;
	list->items[list->nr++] = bundle;
	return 0;
}

/**
 * For use in QSORT() to get a list sorted by creationToken
 * in decreasing order.
 */
static int compare_creation_token_decreasing(const void *va, const void *vb)
{
	const struct remote_bundle_info * const *a = va;
	const struct remote_bundle_info * const *b = vb;

	if ((*a)->creationToken > (*b)->creationToken)
		return -1;
	if ((*a)->creationToken < (*b)->creationToken)
		return 1;
	return 0;
}

static int fetch_bundles_by_token(struct repository *r,
				  struct bundle_list *list)
{
	int cur;
	int move_direction = 0;
	const char *creationTokenStr;
	uint64_t maxCreationToken = 0, newMaxCreationToken = 0;
	struct bundle_list_context ctx = {
		.r = r,
		.list = list,
		.mode = list->mode,
	};
	struct bundles_for_sorting bundles = {
		.alloc = hashmap_get_size(&list->bundles),
	};

	ALLOC_ARRAY(bundles.items, bundles.alloc);

	for_all_bundles_in_list(list, append_bundle, &bundles);

	if (!bundles.nr) {
		free(bundles.items);
		return 0;
	}

	QSORT(bundles.items, bundles.nr, compare_creation_token_decreasing);

	/*
	 * If fetch.bundleCreationToken exists, parses to a uint64t, and
	 * is not strictly smaller than the maximum creation token in the
	 * bundle list, then do not download any bundles.
	 */
	if (!repo_config_get_value(r,
				   "fetch.bundlecreationtoken",
				   &creationTokenStr) &&
	    sscanf(creationTokenStr, "%"PRIu64, &maxCreationToken) == 1 &&
	    bundles.items[0]->creationToken <= maxCreationToken) {
		free(bundles.items);
		return 0;
	}

	/*
	 * Attempt to download and unbundle the minimum number of bundles by
	 * creationToken in decreasing order. If we fail to unbundle (after
	 * a successful download) then move to the next non-downloaded bundle
	 * and attempt downloading. Once we succeed in applying a bundle,
	 * move to the previous unapplied bundle and attempt to unbundle it
	 * again.
	 *
	 * In the case of a fresh clone, we will likely download all of the
	 * bundles before successfully unbundling the oldest one, then the
	 * rest of the bundles unbundle successfully in increasing order
	 * of creationToken.
	 *
	 * If there are existing objects, then this process may terminate
	 * early when all required commits from "new" bundles exist in the
	 * repo's object store.
	 */
	cur = 0;
	while (cur >= 0 && cur < bundles.nr) {
		struct remote_bundle_info *bundle = bundles.items[cur];

		/*
		 * If we need to dig into bundles below the previous
		 * creation token value, then likely we are in an erroneous
		 * state due to missing or invalid bundles. Halt the process
		 * instead of continuing to download extra data.
		 */
		if (bundle->creationToken <= maxCreationToken)
			break;

		if (!bundle->file) {
			/*
			 * Not downloaded yet. Try downloading.
			 *
			 * Note that bundle->file is non-NULL if a download
			 * was attempted, even if it failed to download.
			 */
			if (fetch_bundle_uri_internal(ctx.r, bundle, ctx.depth + 1, ctx.list)) {
				/* Mark as unbundled so we do not retry. */
				bundle->unbundled = 1;

				/* Try looking deeper in the list. */
				move_direction = 1;
				goto move;
			}

			/* We expect bundles when using creationTokens. */
			if (!is_bundle(bundle->file, 1)) {
				warning(_("file downloaded from '%s' is not a bundle"),
					bundle->uri);
				break;
			}
		}

		if (bundle->file && !bundle->unbundled) {
			/*
			 * This was downloaded, but not successfully
			 * unbundled. Try unbundling again.
			 */
			if (unbundle_from_file(ctx.r, bundle->file)) {
				/* Try looking deeper in the list. */
				move_direction = 1;
			} else {
				/*
				 * Succeeded in unbundle. Retry bundles
				 * that previously failed to unbundle.
				 */
				move_direction = -1;
				bundle->unbundled = 1;

				if (bundle->creationToken > newMaxCreationToken)
					newMaxCreationToken = bundle->creationToken;
			}
		}

		/*
		 * Else case: downloaded and unbundled successfully.
		 * Skip this by moving in the same direction as the
		 * previous step.
		 */

move:
		/* Move in the specified direction and repeat. */
		cur += move_direction;
	}

	/*
	 * We succeed if the loop terminates because 'cur' drops below
	 * zero. The other case is that we terminate because 'cur'
	 * reaches the end of the list, so we have a failure no matter
	 * which bundles we apply from the list.
	 */
	if (cur < 0) {
		struct strbuf value = STRBUF_INIT;
		strbuf_addf(&value, "%"PRIu64"", newMaxCreationToken);
		if (repo_config_set_multivar_gently(ctx.r,
						    "fetch.bundleCreationToken",
						    value.buf, NULL, 0))
			warning(_("failed to store maximum creation token"));

		strbuf_release(&value);
	}

	free(bundles.items);
	return cur >= 0;
}

static int download_bundle_list(struct repository *r,
				struct bundle_list *local_list,
				struct bundle_list *global_list,
				int depth)
{
	struct bundle_list_context ctx = {
		.r = r,
		.list = global_list,
		.depth = depth + 1,
		.mode = local_list->mode,
	};

	return for_all_bundles_in_list(local_list, download_bundle_to_file, &ctx);
}

static int fetch_bundle_list_in_config_format(struct repository *r,
					      struct bundle_list *global_list,
					      struct remote_bundle_info *bundle,
					      int depth)
{
	int result;
	struct bundle_list list_from_bundle;

	init_bundle_list(&list_from_bundle);

	if ((result = bundle_uri_parse_config_format(bundle->uri,
						     bundle->file,
						     &list_from_bundle)))
		goto cleanup;

	if (list_from_bundle.mode == BUNDLE_MODE_NONE) {
		warning(_("unrecognized bundle mode from URI '%s'"),
			bundle->uri);
		result = -1;
		goto cleanup;
	}

	/*
	 * If this list uses the creationToken heuristic, then the URIs
	 * it advertises are expected to be bundles, not nested lists.
	 * We can drop 'global_list' and 'depth'.
	 */
	if (list_from_bundle.heuristic == BUNDLE_HEURISTIC_CREATIONTOKEN) {
		result = fetch_bundles_by_token(r, &list_from_bundle);
		global_list->heuristic = BUNDLE_HEURISTIC_CREATIONTOKEN;
	} else if ((result = download_bundle_list(r, &list_from_bundle,
					   global_list, depth)))
		goto cleanup;

cleanup:
	clear_bundle_list(&list_from_bundle);
	return result;
}

/**
 * This limits the recursion on fetch_bundle_uri_internal() when following
 * bundle lists.
 */
static int max_bundle_uri_depth = 4;

/**
 * Recursively download all bundles advertised at the given URI
 * to files. If the file is a bundle, then add it to the given
 * 'list'. Otherwise, expect a bundle list and recurse on the
 * URIs in that list according to the list mode (ANY or ALL).
 */
static int fetch_bundle_uri_internal(struct repository *r,
				     struct remote_bundle_info *bundle,
				     int depth,
				     struct bundle_list *list)
{
	int result = 0;
	struct remote_bundle_info *bcopy;

	if (depth >= max_bundle_uri_depth) {
		warning(_("exceeded bundle URI recursion limit (%d)"),
			max_bundle_uri_depth);
		return -1;
	}

	if (!bundle->file &&
	    !(bundle->file = find_temp_filename())) {
		result = -1;
		goto cleanup;
	}

	if ((result = copy_uri_to_file(bundle->file, bundle->uri))) {
		warning(_("failed to download bundle from URI '%s'"), bundle->uri);
		goto cleanup;
	}

	if ((result = !is_bundle(bundle->file, 1))) {
		result = fetch_bundle_list_in_config_format(
				r, list, bundle, depth);
		if (result)
			warning(_("file at URI '%s' is not a bundle or bundle list"),
				bundle->uri);
		goto cleanup;
	}

	/* Copy the bundle and insert it into the global list. */
	CALLOC_ARRAY(bcopy, 1);
	bcopy->id = xstrdup(bundle->id);
	bcopy->file = xstrdup(bundle->file);
	hashmap_entry_init(&bcopy->ent, strhash(bcopy->id));
	hashmap_add(&list->bundles, &bcopy->ent);

cleanup:
	if (result && bundle->file)
		unlink(bundle->file);
	return result;
}

/**
 * This loop iterator breaks the loop with nonzero return code on the
 * first successful unbundling of a bundle.
 */
static int attempt_unbundle(struct remote_bundle_info *info, void *data)
{
	struct repository *r = data;

	if (!info->file || info->unbundled)
		return 0;

	if (!unbundle_from_file(r, info->file)) {
		info->unbundled = 1;
		return 1;
	}

	return 0;
}

static int unbundle_all_bundles(struct repository *r,
				struct bundle_list *list)
{
	/*
	 * Iterate through all bundles looking for ones that can
	 * successfully unbundle. If any succeed, then perhaps another
	 * will succeed in the next attempt.
	 *
	 * Keep in mind that a non-zero result for the loop here means
	 * the loop terminated early on a successful unbundling, which
	 * signals that we can try again.
	 */
	while (for_all_bundles_in_list(list, attempt_unbundle, r)) ;

	return 0;
}

static int unlink_bundle(struct remote_bundle_info *info, void *data)
{
	if (info->file)
		unlink_or_warn(info->file);
	return 0;
}

int fetch_bundle_uri(struct repository *r, const char *uri,
		     int *has_heuristic)
{
	int result;
	struct bundle_list list;
	struct remote_bundle_info bundle = {
		.uri = xstrdup(uri),
		.id = xstrdup(""),
	};

	init_bundle_list(&list);

	/*
	 * Do not fetch an empty bundle URI. An empty bundle URI
	 * could signal that a configured bundle URI has been disabled.
	 */
	if (!*uri) {
		result = 0;
		goto cleanup;
	}

	/* If a bundle is added to this global list, then it is required. */
	list.mode = BUNDLE_MODE_ALL;

	if ((result = fetch_bundle_uri_internal(r, &bundle, 0, &list)))
		goto cleanup;

	result = unbundle_all_bundles(r, &list);

cleanup:
	if (has_heuristic)
		*has_heuristic = (list.heuristic != BUNDLE_HEURISTIC_NONE);
	for_all_bundles_in_list(&list, unlink_bundle, NULL);
	clear_bundle_list(&list);
	clear_remote_bundle_info(&bundle, NULL);
	return result;
}

int fetch_bundle_list(struct repository *r, struct bundle_list *list)
{
	int result;
	struct bundle_list global_list;

	/*
	 * If the creationToken heuristic is used, then the URIs
	 * advertised by 'list' are not nested lists and instead
	 * direct bundles. We do not need to use global_list.
	 */
	if (list->heuristic == BUNDLE_HEURISTIC_CREATIONTOKEN)
		return fetch_bundles_by_token(r, list);

	init_bundle_list(&global_list);

	/* If a bundle is added to this global list, then it is required. */
	global_list.mode = BUNDLE_MODE_ALL;

	if ((result = download_bundle_list(r, list, &global_list, 0)))
		goto cleanup;

	if (list->heuristic == BUNDLE_HEURISTIC_CREATIONTOKEN)
		result = fetch_bundles_by_token(r, list);
	else
		result = unbundle_all_bundles(r, &global_list);

cleanup:
	for_all_bundles_in_list(&global_list, unlink_bundle, NULL);
	clear_bundle_list(&global_list);
	return result;
}

/**
 * API for serve.c.
 */

int bundle_uri_advertise(struct repository *r, struct strbuf *value UNUSED)
{
	static int advertise_bundle_uri = -1;

	if (advertise_bundle_uri != -1)
		goto cached;

	advertise_bundle_uri = 0;
	repo_config_get_maybe_bool(r, "uploadpack.advertisebundleuris", &advertise_bundle_uri);

cached:
	return advertise_bundle_uri;
}

static int config_to_packet_line(const char *key, const char *value, void *data)
{
	struct packet_reader *writer = data;

	if (starts_with(key, "bundle."))
		packet_write_fmt(writer->fd, "%s=%s", key, value);

	return 0;
}

int bundle_uri_command(struct repository *r,
		       struct packet_reader *request)
{
	struct packet_writer writer;
	packet_writer_init(&writer, 1);

	while (packet_reader_read(request) == PACKET_READ_NORMAL)
		die(_("bundle-uri: unexpected argument: '%s'"), request->line);
	if (request->status != PACKET_READ_FLUSH)
		die(_("bundle-uri: expected flush after arguments"));

	/*
	 * Read all "bundle.*" config lines to the client as key=value
	 * packet lines.
	 */
	repo_config(r, config_to_packet_line, &writer);

	packet_writer_flush(&writer);

	return 0;
}

/**
 * General API for {transport,connect}.c etc.
 */
int bundle_uri_parse_line(struct bundle_list *list, const char *line)
{
	int result;
	const char *equals;
	struct strbuf key = STRBUF_INIT;

	if (!strlen(line))
		return error(_("bundle-uri: got an empty line"));

	equals = strchr(line, '=');

	if (!equals)
		return error(_("bundle-uri: line is not of the form 'key=value'"));
	if (line == equals || !*(equals + 1))
		return error(_("bundle-uri: line has empty key or value"));

	strbuf_add(&key, line, equals - line);
	result = bundle_list_update(key.buf, equals + 1, list);
	strbuf_release(&key);

	return result;
}
