#include "builtin.h"
#include "config.h"
#include "commit.h"
#include "refs.h"
#include "object-store.h"
#include "pkt-line.h"
#include "sideband.h"
#include "run-command.h"
#include "remote.h"
#include "connect.h"
#include "send-pack.h"
#include "quote.h"
#include "transport.h"
#include "version.h"
#include "oid-array.h"
#include "gpg-interface.h"
#include "cache.h"
#include "shallow.h"

int option_parse_push_signed(const struct option *opt,
			     const char *arg, int unset)
{
	if (unset) {
		*(int *)(opt->value) = SEND_PACK_PUSH_CERT_NEVER;
		return 0;
	}
	switch (git_parse_maybe_bool(arg)) {
	case 1:
		*(int *)(opt->value) = SEND_PACK_PUSH_CERT_ALWAYS;
		return 0;
	case 0:
		*(int *)(opt->value) = SEND_PACK_PUSH_CERT_NEVER;
		return 0;
	}
	if (!strcasecmp("if-asked", arg)) {
		*(int *)(opt->value) = SEND_PACK_PUSH_CERT_IF_ASKED;
		return 0;
	}
	die("bad %s argument: %s", opt->long_name, arg);
}

static void feed_object(const struct object_id *oid, FILE *fh, int negative)
{
	if (negative &&
	    !has_object_file_with_flags(oid,
					OBJECT_INFO_SKIP_FETCH_OBJECT |
					OBJECT_INFO_QUICK))
		return;

	if (negative)
		putc('^', fh);
	fputs(oid_to_hex(oid), fh);
	putc('\n', fh);
}

/*
 * Make a pack stream and spit it out into file descriptor fd
 */
static int pack_objects(int fd, struct ref *refs, struct oid_array *advertised,
			struct oid_array *negotiated,
			struct send_pack_args *args)
{
	/*
	 * The child becomes pack-objects --revs; we feed
	 * the revision parameters to it via its stdin and
	 * let its stdout go back to the other end.
	 */
	struct child_process po = CHILD_PROCESS_INIT;
	FILE *po_in;
	int i;
	int rc;

	strvec_push(&po.args, "pack-objects");
	strvec_push(&po.args, "--all-progress-implied");
	strvec_push(&po.args, "--revs");
	strvec_push(&po.args, "--stdout");
	if (args->use_thin_pack)
		strvec_push(&po.args, "--thin");
	if (args->use_ofs_delta)
		strvec_push(&po.args, "--delta-base-offset");
	if (args->quiet || !args->progress)
		strvec_push(&po.args, "-q");
	if (args->progress)
		strvec_push(&po.args, "--progress");
	if (is_repository_shallow(the_repository))
		strvec_push(&po.args, "--shallow");
	if (args->disable_bitmaps)
		strvec_push(&po.args, "--no-use-bitmap-index");
	po.in = -1;
	po.out = args->stateless_rpc ? -1 : fd;
	po.git_cmd = 1;
	po.clean_on_exit = 1;
	if (start_command(&po))
		die_errno("git pack-objects failed");

	/*
	 * We feed the pack-objects we just spawned with revision
	 * parameters by writing to the pipe.
	 */
	po_in = xfdopen(po.in, "w");
	for (i = 0; i < advertised->nr; i++)
		feed_object(&advertised->oid[i], po_in, 1);
	for (i = 0; i < negotiated->nr; i++)
		feed_object(&negotiated->oid[i], po_in, 1);

	while (refs) {
		if (!is_null_oid(&refs->old_oid))
			feed_object(&refs->old_oid, po_in, 1);
		if (!is_null_oid(&refs->new_oid))
			feed_object(&refs->new_oid, po_in, 0);
		refs = refs->next;
	}

	fflush(po_in);
	if (ferror(po_in))
		die_errno("error writing to pack-objects");
	fclose(po_in);

	if (args->stateless_rpc) {
		char *buf = xmalloc(LARGE_PACKET_MAX);
		while (1) {
			ssize_t n = xread(po.out, buf, LARGE_PACKET_MAX);
			if (n <= 0)
				break;
			send_sideband(fd, -1, buf, n, LARGE_PACKET_MAX);
		}
		free(buf);
		close(po.out);
		po.out = -1;
	}

	rc = finish_command(&po);
	if (rc) {
		/*
		 * For a normal non-zero exit, we assume pack-objects wrote
		 * something useful to stderr. For death by signal, though,
		 * we should mention it to the user. The exception is SIGPIPE
		 * (141), because that's a normal occurrence if the remote end
		 * hangs up (and we'll report that by trying to read the unpack
		 * status).
		 */
		if (rc > 128 && rc != 141)
			error("pack-objects died of signal %d", rc - 128);
		return -1;
	}
	return 0;
}

static int receive_unpack_status(struct packet_reader *reader)
{
	if (packet_reader_read(reader) != PACKET_READ_NORMAL)
		return error(_("unexpected flush packet while reading remote unpack status"));
	if (!skip_prefix(reader->line, "unpack ", &reader->line))
		return error(_("unable to parse remote unpack status: %s"), reader->line);
	if (strcmp(reader->line, "ok"))
		return error(_("remote unpack failed: %s"), reader->line);
	return 0;
}

static int receive_status(struct packet_reader *reader, struct ref *refs)
{
	struct ref *hint;
	int ret;
	struct ref_push_report *report = NULL;
	int new_report = 0;
	int once = 0;

	hint = NULL;
	ret = receive_unpack_status(reader);
	while (1) {
		struct object_id old_oid, new_oid;
		const char *head;
		const char *refname;
		char *p;
		if (packet_reader_read(reader) != PACKET_READ_NORMAL)
			break;
		head = reader->line;
		p = strchr(head, ' ');
		if (!p) {
			error("invalid status line from remote: %s", reader->line);
			ret = -1;
			break;
		}
		*p++ = '\0';

		if (!strcmp(head, "option")) {
			const char *key, *val;

			if (!hint || !(report || new_report)) {
				if (!once++)
					error("'option' without a matching 'ok/ng' directive");
				ret = -1;
				continue;
			}
			if (new_report) {
				if (!hint->report) {
					CALLOC_ARRAY(hint->report, 1);
					report = hint->report;
				} else {
					report = hint->report;
					while (report->next)
						report = report->next;
					CALLOC_ARRAY(report->next, 1);
					report = report->next;
				}
				new_report = 0;
			}
			key = p;
			p = strchr(key, ' ');
			if (p)
				*p++ = '\0';
			val = p;
			if (!strcmp(key, "refname"))
				report->ref_name = xstrdup_or_null(val);
			else if (!strcmp(key, "old-oid") && val &&
				 !parse_oid_hex(val, &old_oid, &val))
				report->old_oid = oiddup(&old_oid);
			else if (!strcmp(key, "new-oid") && val &&
				 !parse_oid_hex(val, &new_oid, &val))
				report->new_oid = oiddup(&new_oid);
			else if (!strcmp(key, "forced-update"))
				report->forced_update = 1;
			continue;
		}

		report = NULL;
		new_report = 0;
		if (strcmp(head, "ok") && strcmp(head, "ng")) {
			error("invalid ref status from remote: %s", head);
			ret = -1;
			break;
		}
		refname = p;
		p = strchr(refname, ' ');
		if (p)
			*p++ = '\0';
		/* first try searching at our hint, falling back to all refs */
		if (hint)
			hint = find_ref_by_name(hint, refname);
		if (!hint)
			hint = find_ref_by_name(refs, refname);
		if (!hint) {
			warning("remote reported status on unknown ref: %s",
				refname);
			continue;
		}
		if (hint->status != REF_STATUS_EXPECTING_REPORT &&
		    hint->status != REF_STATUS_OK &&
		    hint->status != REF_STATUS_REMOTE_REJECT) {
			warning("remote reported status on unexpected ref: %s",
				refname);
			continue;
		}
		if (!strcmp(head, "ng")) {
			hint->status = REF_STATUS_REMOTE_REJECT;
			if (p)
				hint->remote_status = xstrdup(p);
			else
				hint->remote_status = "failed";
		} else {
			hint->status = REF_STATUS_OK;
			hint->remote_status = xstrdup_or_null(p);
			new_report = 1;
		}
	}
	return ret;
}

static int sideband_demux(int in, int out, void *data)
{
	int *fd = data, ret;
	if (async_with_fork())
		close(fd[1]);
	ret = recv_sideband("send-pack", fd[0], out);
	close(out);
	return ret;
}

static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *cb)
{
	struct strbuf *sb = cb;
	if (graft->nr_parent == -1)
		packet_buf_write(sb, "shallow %s\n", oid_to_hex(&graft->oid));
	return 0;
}

static void advertise_shallow_grafts_buf(struct strbuf *sb)
{
	if (!is_repository_shallow(the_repository))
		return;
	for_each_commit_graft(advertise_shallow_grafts_cb, sb);
}

#define CHECK_REF_NO_PUSH -1
#define CHECK_REF_STATUS_REJECTED -2
#define CHECK_REF_UPTODATE -3
static int check_to_send_update(const struct ref *ref, const struct send_pack_args *args)
{
	if (!ref->peer_ref && !args->send_mirror)
		return CHECK_REF_NO_PUSH;

	/* Check for statuses set by set_ref_status_for_push() */
	switch (ref->status) {
	case REF_STATUS_REJECT_NONFASTFORWARD:
	case REF_STATUS_REJECT_ALREADY_EXISTS:
	case REF_STATUS_REJECT_FETCH_FIRST:
	case REF_STATUS_REJECT_NEEDS_FORCE:
	case REF_STATUS_REJECT_STALE:
	case REF_STATUS_REJECT_REMOTE_UPDATED:
	case REF_STATUS_REJECT_NODELETE:
		return CHECK_REF_STATUS_REJECTED;
	case REF_STATUS_UPTODATE:
		return CHECK_REF_UPTODATE;

	default:
	case REF_STATUS_EXPECTING_REPORT:
		/* already passed checks on the local side */
	case REF_STATUS_OK:
		/* of course this is OK */
		return 0;
	}
}

/*
 * the beginning of the next line, or the end of buffer.
 *
 * NEEDSWORK: perhaps move this to git-compat-util.h or somewhere and
 * convert many similar uses found by "git grep -A4 memchr".
 */
static const char *next_line(const char *line, size_t len)
{
	const char *nl = memchr(line, '\n', len);
	if (!nl)
		return line + len; /* incomplete line */
	return nl + 1;
}

static int generate_push_cert(struct strbuf *req_buf,
			      const struct ref *remote_refs,
			      struct send_pack_args *args,
			      const char *cap_string,
			      const char *push_cert_nonce)
{
	const struct ref *ref;
	struct string_list_item *item;
	char *signing_key_id = xstrdup(get_signing_key_id());
	const char *cp, *np;
	struct strbuf cert = STRBUF_INIT;
	int update_seen = 0;

	strbuf_addstr(&cert, "certificate version 0.1\n");
	strbuf_addf(&cert, "pusher %s ", signing_key_id);
	datestamp(&cert);
	strbuf_addch(&cert, '\n');
	if (args->url && *args->url) {
		char *anon_url = transport_anonymize_url(args->url);
		strbuf_addf(&cert, "pushee %s\n", anon_url);
		free(anon_url);
	}
	if (push_cert_nonce[0])
		strbuf_addf(&cert, "nonce %s\n", push_cert_nonce);
	if (args->push_options)
		for_each_string_list_item(item, args->push_options)
			strbuf_addf(&cert, "push-option %s\n", item->string);
	strbuf_addstr(&cert, "\n");

	for (ref = remote_refs; ref; ref = ref->next) {
		if (check_to_send_update(ref, args) < 0)
			continue;
		update_seen = 1;
		strbuf_addf(&cert, "%s %s %s\n",
			    oid_to_hex(&ref->old_oid),
			    oid_to_hex(&ref->new_oid),
			    ref->name);
	}
	if (!update_seen)
		goto free_return;

	if (sign_buffer(&cert, &cert, get_signing_key()))
		die(_("failed to sign the push certificate"));

	packet_buf_write(req_buf, "push-cert%c%s", 0, cap_string);
	for (cp = cert.buf; cp < cert.buf + cert.len; cp = np) {
		np = next_line(cp, cert.buf + cert.len - cp);
		packet_buf_write(req_buf,
				 "%.*s", (int)(np - cp), cp);
	}
	packet_buf_write(req_buf, "push-cert-end\n");

free_return:
	free(signing_key_id);
	strbuf_release(&cert);
	return update_seen;
}

#define NONCE_LEN_LIMIT 256

static void reject_invalid_nonce(const char *nonce, int len)
{
	int i = 0;

	if (NONCE_LEN_LIMIT <= len)
		die("the receiving end asked to sign an invalid nonce <%.*s>",
		    len, nonce);

	for (i = 0; i < len; i++) {
		int ch = nonce[i] & 0xFF;
		if (isalnum(ch) ||
		    ch == '-' || ch == '.' ||
		    ch == '/' || ch == '+' ||
		    ch == '=' || ch == '_')
			continue;
		die("the receiving end asked to sign an invalid nonce <%.*s>",
		    len, nonce);
	}
}

static void get_commons_through_negotiation(const char *url,
					    const struct ref *remote_refs,
					    struct oid_array *commons)
{
	struct child_process child = CHILD_PROCESS_INIT;
	const struct ref *ref;
	int len = the_hash_algo->hexsz + 1; /* hash + NL */

	child.git_cmd = 1;
	child.no_stdin = 1;
	child.out = -1;
	strvec_pushl(&child.args, "fetch", "--negotiate-only", NULL);
	for (ref = remote_refs; ref; ref = ref->next) {
		if (!is_null_oid(&ref->new_oid))
			strvec_pushf(&child.args, "--negotiation-tip=%s", oid_to_hex(&ref->new_oid));
	}
	strvec_push(&child.args, url);

	if (start_command(&child))
		die(_("send-pack: unable to fork off fetch subprocess"));

	do {
		char hex_hash[GIT_MAX_HEXSZ + 1];
		int read_len = read_in_full(child.out, hex_hash, len);
		struct object_id oid;
		const char *end;

		if (!read_len)
			break;
		if (read_len != len)
			die("invalid length read %d", read_len);
		if (parse_oid_hex(hex_hash, &oid, &end) || *end != '\n')
			die("invalid hash");
		oid_array_append(commons, &oid);
	} while (1);

	if (finish_command(&child)) {
		/*
		 * The information that push negotiation provides is useful but
		 * not mandatory.
		 */
		warning(_("push negotiation failed; proceeding anyway with push"));
	}
}

int send_pack(struct send_pack_args *args,
	      int fd[], struct child_process *conn,
	      struct ref *remote_refs,
	      struct oid_array *extra_have)
{
	struct oid_array commons = OID_ARRAY_INIT;
	int in = fd[0];
	int out = fd[1];
	struct strbuf req_buf = STRBUF_INIT;
	struct strbuf cap_buf = STRBUF_INIT;
	struct ref *ref;
	int need_pack_data = 0;
	int allow_deleting_refs = 0;
	int status_report = 0;
	int use_sideband = 0;
	int quiet_supported = 0;
	int agent_supported = 0;
	int advertise_sid = 0;
	int push_negotiate = 0;
	int use_atomic = 0;
	int atomic_supported = 0;
	int use_push_options = 0;
	int push_options_supported = 0;
	int object_format_supported = 0;
	unsigned cmds_sent = 0;
	int ret;
	struct async demux;
	const char *push_cert_nonce = NULL;
	struct packet_reader reader;
	int use_bitmaps;

	if (!remote_refs) {
		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
			"Perhaps you should specify a branch.\n");
		return 0;
	}

	git_config_get_bool("push.negotiate", &push_negotiate);
	if (push_negotiate)
		get_commons_through_negotiation(args->url, remote_refs, &commons);

	if (!git_config_get_bool("push.usebitmaps", &use_bitmaps))
		args->disable_bitmaps = !use_bitmaps;

	git_config_get_bool("transfer.advertisesid", &advertise_sid);

	/* Does the other end support the reporting? */
	if (server_supports("report-status-v2"))
		status_report = 2;
	else if (server_supports("report-status"))
		status_report = 1;
	if (server_supports("delete-refs"))
		allow_deleting_refs = 1;
	if (server_supports("ofs-delta"))
		args->use_ofs_delta = 1;
	if (server_supports("side-band-64k"))
		use_sideband = 1;
	if (server_supports("quiet"))
		quiet_supported = 1;
	if (server_supports("agent"))
		agent_supported = 1;
	if (!server_supports("session-id"))
		advertise_sid = 0;
	if (server_supports("no-thin"))
		args->use_thin_pack = 0;
	if (server_supports("atomic"))
		atomic_supported = 1;
	if (server_supports("push-options"))
		push_options_supported = 1;

	if (!server_supports_hash(the_hash_algo->name, &object_format_supported))
		die(_("the receiving end does not support this repository's hash algorithm"));

	if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) {
		int len;
		push_cert_nonce = server_feature_value("push-cert", &len);
		if (push_cert_nonce) {
			reject_invalid_nonce(push_cert_nonce, len);
			push_cert_nonce = xmemdupz(push_cert_nonce, len);
		} else if (args->push_cert == SEND_PACK_PUSH_CERT_ALWAYS) {
			die(_("the receiving end does not support --signed push"));
		} else if (args->push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) {
			warning(_("not sending a push certificate since the"
				  " receiving end does not support --signed"
				  " push"));
		}
	}

	if (args->atomic && !atomic_supported)
		die(_("the receiving end does not support --atomic push"));

	use_atomic = atomic_supported && args->atomic;

	if (args->push_options && !push_options_supported)
		die(_("the receiving end does not support push options"));

	use_push_options = push_options_supported && args->push_options;

	if (status_report == 1)
		strbuf_addstr(&cap_buf, " report-status");
	else if (status_report == 2)
		strbuf_addstr(&cap_buf, " report-status-v2");
	if (use_sideband)
		strbuf_addstr(&cap_buf, " side-band-64k");
	if (quiet_supported && (args->quiet || !args->progress))
		strbuf_addstr(&cap_buf, " quiet");
	if (use_atomic)
		strbuf_addstr(&cap_buf, " atomic");
	if (use_push_options)
		strbuf_addstr(&cap_buf, " push-options");
	if (object_format_supported)
		strbuf_addf(&cap_buf, " object-format=%s", the_hash_algo->name);
	if (agent_supported)
		strbuf_addf(&cap_buf, " agent=%s", git_user_agent_sanitized());
	if (advertise_sid)
		strbuf_addf(&cap_buf, " session-id=%s", trace2_session_id());

	/*
	 * NEEDSWORK: why does delete-refs have to be so specific to
	 * send-pack machinery that set_ref_status_for_push() cannot
	 * set this bit for us???
	 */
	for (ref = remote_refs; ref; ref = ref->next)
		if (ref->deletion && !allow_deleting_refs)
			ref->status = REF_STATUS_REJECT_NODELETE;

	/*
	 * Clear the status for each ref and see if we need to send
	 * the pack data.
	 */
	for (ref = remote_refs; ref; ref = ref->next) {
		switch (check_to_send_update(ref, args)) {
		case 0: /* no error */
			break;
		case CHECK_REF_STATUS_REJECTED:
			/*
			 * When we know the server would reject a ref update if
			 * we were to send it and we're trying to send the refs
			 * atomically, abort the whole operation.
			 */
			if (use_atomic) {
				strbuf_release(&req_buf);
				strbuf_release(&cap_buf);
				reject_atomic_push(remote_refs, args->send_mirror);
				error("atomic push failed for ref %s. status: %d\n",
				      ref->name, ref->status);
				return args->porcelain ? 0 : -1;
			}
			/* else fallthrough */
		default:
			continue;
		}
		if (!ref->deletion)
			need_pack_data = 1;

		if (args->dry_run || !status_report)
			ref->status = REF_STATUS_OK;
		else
			ref->status = REF_STATUS_EXPECTING_REPORT;
	}

	if (!args->dry_run)
		advertise_shallow_grafts_buf(&req_buf);

	/*
	 * Finally, tell the other end!
	 */
	if (!args->dry_run && push_cert_nonce)
		cmds_sent = generate_push_cert(&req_buf, remote_refs, args,
					       cap_buf.buf, push_cert_nonce);
	else if (!args->dry_run)
		for (ref = remote_refs; ref; ref = ref->next) {
			char *old_hex, *new_hex;

			if (check_to_send_update(ref, args) < 0)
				continue;

			old_hex = oid_to_hex(&ref->old_oid);
			new_hex = oid_to_hex(&ref->new_oid);
			if (!cmds_sent) {
				packet_buf_write(&req_buf,
						 "%s %s %s%c%s",
						 old_hex, new_hex, ref->name, 0,
						 cap_buf.buf);
				cmds_sent = 1;
			} else {
				packet_buf_write(&req_buf, "%s %s %s",
						 old_hex, new_hex, ref->name);
			}
		}

	if (use_push_options) {
		struct string_list_item *item;

		packet_buf_flush(&req_buf);
		for_each_string_list_item(item, args->push_options)
			packet_buf_write(&req_buf, "%s", item->string);
	}

	if (args->stateless_rpc) {
		if (!args->dry_run && (cmds_sent || is_repository_shallow(the_repository))) {
			packet_buf_flush(&req_buf);
			send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX);
		}
	} else {
		write_or_die(out, req_buf.buf, req_buf.len);
		packet_flush(out);
	}
	strbuf_release(&req_buf);
	strbuf_release(&cap_buf);

	if (use_sideband && cmds_sent) {
		memset(&demux, 0, sizeof(demux));
		demux.proc = sideband_demux;
		demux.data = fd;
		demux.out = -1;
		demux.isolate_sigpipe = 1;
		if (start_async(&demux))
			die("send-pack: unable to fork off sideband demultiplexer");
		in = demux.out;
	}

	packet_reader_init(&reader, in, NULL, 0,
			   PACKET_READ_CHOMP_NEWLINE |
			   PACKET_READ_DIE_ON_ERR_PACKET);

	if (need_pack_data && cmds_sent) {
		if (pack_objects(out, remote_refs, extra_have, &commons, args) < 0) {
			if (args->stateless_rpc)
				close(out);
			if (git_connection_is_socket(conn))
				shutdown(fd[0], SHUT_WR);

			/*
			 * Do not even bother with the return value; we know we
			 * are failing, and just want the error() side effects,
			 * as well as marking refs with their remote status (if
			 * we get one).
			 */
			if (status_report)
				receive_status(&reader, remote_refs);

			if (use_sideband) {
				close(demux.out);
				finish_async(&demux);
			}
			fd[1] = -1;
			return -1;
		}
		if (!args->stateless_rpc)
			/* Closed by pack_objects() via start_command() */
			fd[1] = -1;
	}
	if (args->stateless_rpc && cmds_sent)
		packet_flush(out);

	if (status_report && cmds_sent)
		ret = receive_status(&reader, remote_refs);
	else
		ret = 0;
	if (args->stateless_rpc)
		packet_flush(out);

	if (use_sideband && cmds_sent) {
		close(demux.out);
		if (finish_async(&demux)) {
			error("error in sideband demultiplexer");
			ret = -1;
		}
	}

	if (ret < 0)
		return ret;

	if (args->porcelain)
		return 0;

	for (ref = remote_refs; ref; ref = ref->next) {
		switch (ref->status) {
		case REF_STATUS_NONE:
		case REF_STATUS_UPTODATE:
		case REF_STATUS_OK:
			break;
		default:
			return -1;
		}
	}
	return 0;
}
