/*
  Copyright 2020 Google LLC

  Use of this source code is governed by a BSD-style
  license that can be found in the LICENSE file or at
  https://developers.google.com/open-source/licenses/bsd
*/

#include "system.h"
#include "reftable-error.h"
#include "basics.h"
#include "refname.h"
#include "reftable-iterator.h"

struct find_arg {
	char **names;
	const char *want;
};

static int find_name(size_t k, void *arg)
{
	struct find_arg *f_arg = arg;
	return strcmp(f_arg->names[k], f_arg->want) >= 0;
}

static int modification_has_ref(struct modification *mod, const char *name)
{
	struct reftable_ref_record ref = { NULL };
	int err = 0;

	if (mod->add_len > 0) {
		struct find_arg arg = {
			.names = mod->add,
			.want = name,
		};
		int idx = binsearch(mod->add_len, find_name, &arg);
		if (idx < mod->add_len && !strcmp(mod->add[idx], name)) {
			return 0;
		}
	}

	if (mod->del_len > 0) {
		struct find_arg arg = {
			.names = mod->del,
			.want = name,
		};
		int idx = binsearch(mod->del_len, find_name, &arg);
		if (idx < mod->del_len && !strcmp(mod->del[idx], name)) {
			return 1;
		}
	}

	err = reftable_table_read_ref(&mod->tab, name, &ref);
	reftable_ref_record_release(&ref);
	return err;
}

static void modification_release(struct modification *mod)
{
	/* don't delete the strings themselves; they're owned by ref records.
	 */
	FREE_AND_NULL(mod->add);
	FREE_AND_NULL(mod->del);
	mod->add_len = 0;
	mod->del_len = 0;
}

static int modification_has_ref_with_prefix(struct modification *mod,
					    const char *prefix)
{
	struct reftable_iterator it = { NULL };
	struct reftable_ref_record ref = { NULL };
	int err = 0;

	if (mod->add_len > 0) {
		struct find_arg arg = {
			.names = mod->add,
			.want = prefix,
		};
		int idx = binsearch(mod->add_len, find_name, &arg);
		if (idx < mod->add_len &&
		    !strncmp(prefix, mod->add[idx], strlen(prefix)))
			goto done;
	}
	err = reftable_table_seek_ref(&mod->tab, &it, prefix);
	if (err)
		goto done;

	while (1) {
		err = reftable_iterator_next_ref(&it, &ref);
		if (err)
			goto done;

		if (mod->del_len > 0) {
			struct find_arg arg = {
				.names = mod->del,
				.want = ref.refname,
			};
			int idx = binsearch(mod->del_len, find_name, &arg);
			if (idx < mod->del_len &&
			    !strcmp(ref.refname, mod->del[idx])) {
				continue;
			}
		}

		if (strncmp(ref.refname, prefix, strlen(prefix))) {
			err = 1;
			goto done;
		}
		err = 0;
		goto done;
	}

done:
	reftable_ref_record_release(&ref);
	reftable_iterator_destroy(&it);
	return err;
}

static int validate_refname(const char *name)
{
	while (1) {
		char *next = strchr(name, '/');
		if (!*name) {
			return REFTABLE_REFNAME_ERROR;
		}
		if (!next) {
			return 0;
		}
		if (next - name == 0 || (next - name == 1 && *name == '.') ||
		    (next - name == 2 && name[0] == '.' && name[1] == '.'))
			return REFTABLE_REFNAME_ERROR;
		name = next + 1;
	}
	return 0;
}

int validate_ref_record_addition(struct reftable_table tab,
				 struct reftable_ref_record *recs, size_t sz)
{
	struct modification mod = {
		.tab = tab,
		.add = reftable_calloc(sizeof(char *) * sz),
		.del = reftable_calloc(sizeof(char *) * sz),
	};
	int i = 0;
	int err = 0;
	for (; i < sz; i++) {
		if (reftable_ref_record_is_deletion(&recs[i])) {
			mod.del[mod.del_len++] = recs[i].refname;
		} else {
			mod.add[mod.add_len++] = recs[i].refname;
		}
	}

	err = modification_validate(&mod);
	modification_release(&mod);
	return err;
}

static void strbuf_trim_component(struct strbuf *sl)
{
	while (sl->len > 0) {
		int is_slash = (sl->buf[sl->len - 1] == '/');
		strbuf_setlen(sl, sl->len - 1);
		if (is_slash)
			break;
	}
}

int modification_validate(struct modification *mod)
{
	struct strbuf slashed = STRBUF_INIT;
	int err = 0;
	int i = 0;
	for (; i < mod->add_len; i++) {
		err = validate_refname(mod->add[i]);
		if (err)
			goto done;
		strbuf_reset(&slashed);
		strbuf_addstr(&slashed, mod->add[i]);
		strbuf_addstr(&slashed, "/");

		err = modification_has_ref_with_prefix(mod, slashed.buf);
		if (err == 0) {
			err = REFTABLE_NAME_CONFLICT;
			goto done;
		}
		if (err < 0)
			goto done;

		strbuf_reset(&slashed);
		strbuf_addstr(&slashed, mod->add[i]);
		while (slashed.len) {
			strbuf_trim_component(&slashed);
			err = modification_has_ref(mod, slashed.buf);
			if (err == 0) {
				err = REFTABLE_NAME_CONFLICT;
				goto done;
			}
			if (err < 0)
				goto done;
		}
	}
	err = 0;
done:
	strbuf_release(&slashed);
	return err;
}
