#include "cache.h"
#include "config.h"
#include "refs.h"
#include "builtin.h"
#include "parse-options.h"
#include "quote.h"
#include "argv-array.h"

static const char * const git_update_ref_usage[] = {
	N_("git update-ref [<options>] -d <refname> [<old-val>]"),
	N_("git update-ref [<options>]    <refname> <new-val> [<old-val>]"),
	N_("git update-ref [<options>] --stdin [-z]"),
	NULL
};

static char line_termination = '\n';
static unsigned int update_flags;
static unsigned int default_flags;
static unsigned create_reflog_flag;
static const char *msg;

/*
 * Parse one whitespace- or NUL-terminated, possibly C-quoted argument
 * and append the result to arg.  Return a pointer to the terminator.
 * Die if there is an error in how the argument is C-quoted.  This
 * function is only used if not -z.
 */
static const char *parse_arg(const char *next, struct strbuf *arg)
{
	if (*next == '"') {
		const char *orig = next;

		if (unquote_c_style(arg, next, &next))
			die("badly quoted argument: %s", orig);
		if (*next && !isspace(*next))
			die("unexpected character after quoted argument: %s", orig);
	} else {
		while (*next && !isspace(*next))
			strbuf_addch(arg, *next++);
	}

	return next;
}

/*
 * Parse the reference name immediately after "command SP".  If not
 * -z, then handle C-quoting.  Return a pointer to a newly allocated
 * string containing the name of the reference, or NULL if there was
 * an error.  Update *next to point at the character that terminates
 * the argument.  Die if C-quoting is malformed or the reference name
 * is invalid.
 */
static char *parse_refname(const char **next)
{
	struct strbuf ref = STRBUF_INIT;

	if (line_termination) {
		/* Without -z, use the next argument */
		*next = parse_arg(*next, &ref);
	} else {
		/* With -z, use everything up to the next NUL */
		strbuf_addstr(&ref, *next);
		*next += ref.len;
	}

	if (!ref.len) {
		strbuf_release(&ref);
		return NULL;
	}

	if (check_refname_format(ref.buf, REFNAME_ALLOW_ONELEVEL))
		die("invalid ref format: %s", ref.buf);

	return strbuf_detach(&ref, NULL);
}

/*
 * The value being parsed is <oldvalue> (as opposed to <newvalue>; the
 * difference affects which error messages are generated):
 */
#define PARSE_SHA1_OLD 0x01

/*
 * For backwards compatibility, accept an empty string for update's
 * <newvalue> in binary mode to be equivalent to specifying zeros.
 */
#define PARSE_SHA1_ALLOW_EMPTY 0x02

/*
 * Parse an argument separator followed by the next argument, if any.
 * If there is an argument, convert it to a SHA-1, write it to sha1,
 * set *next to point at the character terminating the argument, and
 * return 0.  If there is no argument at all (not even the empty
 * string), return 1 and leave *next unchanged.  If the value is
 * provided but cannot be converted to a SHA-1, die.  flags can
 * include PARSE_SHA1_OLD and/or PARSE_SHA1_ALLOW_EMPTY.
 */
static int parse_next_oid(const char **next, const char *end,
			  struct object_id *oid,
			  const char *command, const char *refname,
			  int flags)
{
	struct strbuf arg = STRBUF_INIT;
	int ret = 0;

	if (*next == end)
		goto eof;

	if (line_termination) {
		/* Without -z, consume SP and use next argument */
		if (!**next || **next == line_termination)
			return 1;
		if (**next != ' ')
			die("%s %s: expected SP but got: %s",
			    command, refname, *next);
		(*next)++;
		*next = parse_arg(*next, &arg);
		if (arg.len) {
			if (get_oid(arg.buf, oid))
				goto invalid;
		} else {
			/* Without -z, an empty value means all zeros: */
			oidclr(oid);
		}
	} else {
		/* With -z, read the next NUL-terminated line */
		if (**next)
			die("%s %s: expected NUL but got: %s",
			    command, refname, *next);
		(*next)++;
		if (*next == end)
			goto eof;
		strbuf_addstr(&arg, *next);
		*next += arg.len;

		if (arg.len) {
			if (get_oid(arg.buf, oid))
				goto invalid;
		} else if (flags & PARSE_SHA1_ALLOW_EMPTY) {
			/* With -z, treat an empty value as all zeros: */
			warning("%s %s: missing <newvalue>, treating as zero",
				command, refname);
			oidclr(oid);
		} else {
			/*
			 * With -z, an empty non-required value means
			 * unspecified:
			 */
			ret = 1;
		}
	}

	strbuf_release(&arg);

	return ret;

 invalid:
	die(flags & PARSE_SHA1_OLD ?
	    "%s %s: invalid <oldvalue>: %s" :
	    "%s %s: invalid <newvalue>: %s",
	    command, refname, arg.buf);

 eof:
	die(flags & PARSE_SHA1_OLD ?
	    "%s %s: unexpected end of input when reading <oldvalue>" :
	    "%s %s: unexpected end of input when reading <newvalue>",
	    command, refname);
}


/*
 * The following five parse_cmd_*() functions parse the corresponding
 * command.  In each case, next points at the character following the
 * command name and the following space.  They each return a pointer
 * to the character terminating the command, and die with an
 * explanatory message if there are any parsing problems.  All of
 * these functions handle either text or binary format input,
 * depending on how line_termination is set.
 */

static void parse_cmd_update(struct ref_transaction *transaction,
			     const char *next, const char *end)
{
	struct strbuf err = STRBUF_INIT;
	char *refname;
	struct object_id new_oid, old_oid;
	int have_old;

	refname = parse_refname(&next);
	if (!refname)
		die("update: missing <ref>");

	if (parse_next_oid(&next, end, &new_oid, "update", refname,
			   PARSE_SHA1_ALLOW_EMPTY))
		die("update %s: missing <newvalue>", refname);

	have_old = !parse_next_oid(&next, end, &old_oid, "update", refname,
				   PARSE_SHA1_OLD);

	if (*next != line_termination)
		die("update %s: extra input: %s", refname, next);

	if (ref_transaction_update(transaction, refname,
				   &new_oid, have_old ? &old_oid : NULL,
				   update_flags | create_reflog_flag,
				   msg, &err))
		die("%s", err.buf);

	update_flags = default_flags;
	free(refname);
	strbuf_release(&err);
}

static void parse_cmd_create(struct ref_transaction *transaction,
			     const char *next, const char *end)
{
	struct strbuf err = STRBUF_INIT;
	char *refname;
	struct object_id new_oid;

	refname = parse_refname(&next);
	if (!refname)
		die("create: missing <ref>");

	if (parse_next_oid(&next, end, &new_oid, "create", refname, 0))
		die("create %s: missing <newvalue>", refname);

	if (is_null_oid(&new_oid))
		die("create %s: zero <newvalue>", refname);

	if (*next != line_termination)
		die("create %s: extra input: %s", refname, next);

	if (ref_transaction_create(transaction, refname, &new_oid,
				   update_flags | create_reflog_flag,
				   msg, &err))
		die("%s", err.buf);

	update_flags = default_flags;
	free(refname);
	strbuf_release(&err);
}

static void parse_cmd_delete(struct ref_transaction *transaction,
			     const char *next, const char *end)
{
	struct strbuf err = STRBUF_INIT;
	char *refname;
	struct object_id old_oid;
	int have_old;

	refname = parse_refname(&next);
	if (!refname)
		die("delete: missing <ref>");

	if (parse_next_oid(&next, end, &old_oid, "delete", refname,
			   PARSE_SHA1_OLD)) {
		have_old = 0;
	} else {
		if (is_null_oid(&old_oid))
			die("delete %s: zero <oldvalue>", refname);
		have_old = 1;
	}

	if (*next != line_termination)
		die("delete %s: extra input: %s", refname, next);

	if (ref_transaction_delete(transaction, refname,
				   have_old ? &old_oid : NULL,
				   update_flags, msg, &err))
		die("%s", err.buf);

	update_flags = default_flags;
	free(refname);
	strbuf_release(&err);
}

static void parse_cmd_verify(struct ref_transaction *transaction,
			     const char *next, const char *end)
{
	struct strbuf err = STRBUF_INIT;
	char *refname;
	struct object_id old_oid;

	refname = parse_refname(&next);
	if (!refname)
		die("verify: missing <ref>");

	if (parse_next_oid(&next, end, &old_oid, "verify", refname,
			   PARSE_SHA1_OLD))
		oidclr(&old_oid);

	if (*next != line_termination)
		die("verify %s: extra input: %s", refname, next);

	if (ref_transaction_verify(transaction, refname, &old_oid,
				   update_flags, &err))
		die("%s", err.buf);

	update_flags = default_flags;
	free(refname);
	strbuf_release(&err);
}

static void parse_cmd_option(struct ref_transaction *transaction,
			     const char *next, const char *end)
{
	const char *rest;
	if (skip_prefix(next, "no-deref", &rest) && *rest == line_termination)
		update_flags |= REF_NO_DEREF;
	else
		die("option unknown: %s", next);
}

static void parse_cmd_start(struct ref_transaction *transaction,
			    const char *next, const char *end)
{
	if (*next != line_termination)
		die("start: extra input: %s", next);
	puts("start: ok");
}

static void parse_cmd_prepare(struct ref_transaction *transaction,
			      const char *next, const char *end)
{
	struct strbuf error = STRBUF_INIT;
	if (*next != line_termination)
		die("prepare: extra input: %s", next);
	if (ref_transaction_prepare(transaction, &error))
		die("prepare: %s", error.buf);
	puts("prepare: ok");
}

static void parse_cmd_abort(struct ref_transaction *transaction,
			    const char *next, const char *end)
{
	struct strbuf error = STRBUF_INIT;
	if (*next != line_termination)
		die("abort: extra input: %s", next);
	if (ref_transaction_abort(transaction, &error))
		die("abort: %s", error.buf);
	puts("abort: ok");
}

static void parse_cmd_commit(struct ref_transaction *transaction,
			     const char *next, const char *end)
{
	struct strbuf error = STRBUF_INIT;
	if (*next != line_termination)
		die("commit: extra input: %s", next);
	if (ref_transaction_commit(transaction, &error))
		die("commit: %s", error.buf);
	puts("commit: ok");
	ref_transaction_free(transaction);
}

enum update_refs_state {
	/* Non-transactional state open for updates. */
	UPDATE_REFS_OPEN,
	/* A transaction has been started. */
	UPDATE_REFS_STARTED,
	/* References are locked and ready for commit */
	UPDATE_REFS_PREPARED,
	/* Transaction has been committed or closed. */
	UPDATE_REFS_CLOSED,
};

static const struct parse_cmd {
	const char *prefix;
	void (*fn)(struct ref_transaction *, const char *, const char *);
	unsigned args;
	enum update_refs_state state;
} command[] = {
	{ "update",  parse_cmd_update,  3, UPDATE_REFS_OPEN },
	{ "create",  parse_cmd_create,  2, UPDATE_REFS_OPEN },
	{ "delete",  parse_cmd_delete,  2, UPDATE_REFS_OPEN },
	{ "verify",  parse_cmd_verify,  2, UPDATE_REFS_OPEN },
	{ "option",  parse_cmd_option,  1, UPDATE_REFS_OPEN },
	{ "start",   parse_cmd_start,   0, UPDATE_REFS_STARTED },
	{ "prepare", parse_cmd_prepare, 0, UPDATE_REFS_PREPARED },
	{ "abort",   parse_cmd_abort,   0, UPDATE_REFS_CLOSED },
	{ "commit",  parse_cmd_commit,  0, UPDATE_REFS_CLOSED },
};

static void update_refs_stdin(void)
{
	struct strbuf input = STRBUF_INIT, err = STRBUF_INIT;
	enum update_refs_state state = UPDATE_REFS_OPEN;
	struct ref_transaction *transaction;
	int i, j;

	transaction = ref_transaction_begin(&err);
	if (!transaction)
		die("%s", err.buf);

	/* Read each line dispatch its command */
	while (!strbuf_getwholeline(&input, stdin, line_termination)) {
		const struct parse_cmd *cmd = NULL;

		if (*input.buf == line_termination)
			die("empty command in input");
		else if (isspace(*input.buf))
			die("whitespace before command: %s", input.buf);

		for (i = 0; i < ARRAY_SIZE(command); i++) {
			const char *prefix = command[i].prefix;
			char c;

			if (!starts_with(input.buf, prefix))
				continue;

			/*
			 * If the command has arguments, verify that it's
			 * followed by a space. Otherwise, it shall be followed
			 * by a line terminator.
			 */
			c = command[i].args ? ' ' : line_termination;
			if (input.buf[strlen(prefix)] != c)
				continue;

			cmd = &command[i];
			break;
		}
		if (!cmd)
			die("unknown command: %s", input.buf);

		/*
		 * Read additional arguments if NUL-terminated. Do not raise an
		 * error in case there is an early EOF to let the command
		 * handle missing arguments with a proper error message.
		 */
		for (j = 1; line_termination == '\0' && j < cmd->args; j++)
			if (strbuf_appendwholeline(&input, stdin, line_termination))
				break;

		switch (state) {
		case UPDATE_REFS_OPEN:
		case UPDATE_REFS_STARTED:
			/* Do not downgrade a transaction to a non-transaction. */
			if (cmd->state >= state)
				state = cmd->state;
			break;
		case UPDATE_REFS_PREPARED:
			if (cmd->state != UPDATE_REFS_CLOSED)
				die("prepared transactions can only be closed");
			state = cmd->state;
			break;
		case UPDATE_REFS_CLOSED:
			die("transaction is closed");
			break;
		}

		cmd->fn(transaction, input.buf + strlen(cmd->prefix) + !!cmd->args,
			input.buf + input.len);
	}

	switch (state) {
	case UPDATE_REFS_OPEN:
		/* Commit by default if no transaction was requested. */
		if (ref_transaction_commit(transaction, &err))
			die("%s", err.buf);
		ref_transaction_free(transaction);
		break;
	case UPDATE_REFS_STARTED:
	case UPDATE_REFS_PREPARED:
		/* If using a transaction, we want to abort it. */
		if (ref_transaction_abort(transaction, &err))
			die("%s", err.buf);
		break;
	case UPDATE_REFS_CLOSED:
		/* Otherwise no need to do anything, the transaction was closed already. */
		break;
	}

	strbuf_release(&err);
	strbuf_release(&input);
}

int cmd_update_ref(int argc, const char **argv, const char *prefix)
{
	const char *refname, *oldval;
	struct object_id oid, oldoid;
	int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0;
	int create_reflog = 0;
	struct option options[] = {
		OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")),
		OPT_BOOL('d', NULL, &delete, N_("delete the reference")),
		OPT_BOOL( 0 , "no-deref", &no_deref,
					N_("update <refname> not the one it points to")),
		OPT_BOOL('z', NULL, &end_null, N_("stdin has NUL-terminated arguments")),
		OPT_BOOL( 0 , "stdin", &read_stdin, N_("read updates from stdin")),
		OPT_BOOL( 0 , "create-reflog", &create_reflog, N_("create a reflog")),
		OPT_END(),
	};

	git_config(git_default_config, NULL);
	argc = parse_options(argc, argv, prefix, options, git_update_ref_usage,
			     0);
	if (msg && !*msg)
		die("Refusing to perform update with empty message.");

	create_reflog_flag = create_reflog ? REF_FORCE_CREATE_REFLOG : 0;

	if (no_deref) {
		default_flags = REF_NO_DEREF;
		update_flags = default_flags;
	}

	if (read_stdin) {
		if (delete || argc > 0)
			usage_with_options(git_update_ref_usage, options);
		if (end_null)
			line_termination = '\0';
		update_refs_stdin();
		return 0;
	}

	if (end_null)
		usage_with_options(git_update_ref_usage, options);

	if (delete) {
		if (argc < 1 || argc > 2)
			usage_with_options(git_update_ref_usage, options);
		refname = argv[0];
		oldval = argv[1];
	} else {
		const char *value;
		if (argc < 2 || argc > 3)
			usage_with_options(git_update_ref_usage, options);
		refname = argv[0];
		value = argv[1];
		oldval = argv[2];
		if (get_oid(value, &oid))
			die("%s: not a valid SHA1", value);
	}

	if (oldval) {
		if (!*oldval)
			/*
			 * The empty string implies that the reference
			 * must not already exist:
			 */
			oidclr(&oldoid);
		else if (get_oid(oldval, &oldoid))
			die("%s: not a valid old SHA1", oldval);
	}

	if (delete)
		/*
		 * For purposes of backwards compatibility, we treat
		 * NULL_SHA1 as "don't care" here:
		 */
		return delete_ref(msg, refname,
				  (oldval && !is_null_oid(&oldoid)) ? &oldoid : NULL,
				  default_flags);
	else
		return update_ref(msg, refname, &oid, oldval ? &oldoid : NULL,
				  default_flags | create_reflog_flag,
				  UPDATE_REFS_DIE_ON_ERR);
}
