/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "common.h"
#include "fileops.h"
#include "hash.h"
#include "filter.h"
#include "repository.h"
#include "global.h"
#include "git2/sys/filter.h"
#include "git2/config.h"
#include "blob.h"
#include "attr_file.h"
#include "array.h"

struct git_filter_source {
	git_repository *repo;
	const char     *path;
	git_oid         oid;  /* zero if unknown (which is likely) */
	uint16_t        filemode; /* zero if unknown */
	git_filter_mode_t mode;
};

typedef struct {
	git_filter *filter;
	void *payload;
} git_filter_entry;

struct git_filter_list {
	git_array_t(git_filter_entry) filters;
	git_filter_source source;
	char path[GIT_FLEX_ARRAY];
};

typedef struct {
	const char *filter_name;
	git_filter *filter;
	int priority;
	int initialized;
	size_t nattrs, nmatches;
	char *attrdata;
	const char *attrs[GIT_FLEX_ARRAY];
} git_filter_def;

static int filter_def_priority_cmp(const void *a, const void *b)
{
	int pa = ((const git_filter_def *)a)->priority;
	int pb = ((const git_filter_def *)b)->priority;
	return (pa < pb) ? -1 : (pa > pb) ? 1 : 0;
}

struct filter_registry {
	git_vector filters;
};

static struct filter_registry *git__filter_registry = NULL;

static void filter_registry_shutdown(void)
{
	struct filter_registry *reg = NULL;
	size_t pos;
	git_filter_def *fdef;

	if ((reg = git__swap(git__filter_registry, NULL)) == NULL)
		return;

	git_vector_foreach(&reg->filters, pos, fdef) {
		if (fdef->initialized && fdef->filter && fdef->filter->shutdown) {
			fdef->filter->shutdown(fdef->filter);
			fdef->initialized = false;
		}

		git__free(fdef->attrdata);
		git__free(fdef);
	}

	git_vector_free(&reg->filters);
	git__free(reg);
}

static int filter_registry_initialize(void)
{
	int error = 0;
	struct filter_registry *reg;

	if (git__filter_registry)
		return 0;

	reg = git__calloc(1, sizeof(struct filter_registry));
	GITERR_CHECK_ALLOC(reg);

	if ((error = git_vector_init(
			&reg->filters, 2, filter_def_priority_cmp)) < 0)
		goto cleanup;

	reg = git__compare_and_swap(&git__filter_registry, NULL, reg);
	if (reg != NULL)
		goto cleanup;

	git__on_shutdown(filter_registry_shutdown);

	/* try to register both default filters */
	{
		git_filter *crlf = git_crlf_filter_new();
		git_filter *ident = git_ident_filter_new();

		if (crlf && git_filter_register(
				GIT_FILTER_CRLF, crlf, GIT_FILTER_CRLF_PRIORITY) < 0)
			crlf = NULL;
		if (ident && git_filter_register(
				GIT_FILTER_IDENT, ident, GIT_FILTER_IDENT_PRIORITY) < 0)
			ident = NULL;

		if (!crlf || !ident)
			return -1;
	}

	return 0;

cleanup:
	git_vector_free(&reg->filters);
	git__free(reg);
	return error;
}

static int filter_def_scan_attrs(
	git_buf *attrs, size_t *nattr, size_t *nmatch, const char *attr_str)
{
	const char *start, *scan = attr_str;
	int has_eq;

	*nattr = *nmatch = 0;

	if (!scan)
		return 0;

	while (*scan) {
		while (git__isspace(*scan)) scan++;

		for (start = scan, has_eq = 0; *scan && !git__isspace(*scan); ++scan) {
			if (*scan == '=')
				has_eq = 1;
		}

		if (scan > start) {
			(*nattr)++;
			if (has_eq || *start == '-' || *start == '+' || *start == '!')
				(*nmatch)++;

			if (has_eq)
				git_buf_putc(attrs, '=');
			git_buf_put(attrs, start, scan - start);
			git_buf_putc(attrs, '\0');
		}
	}

	return 0;
}

static void filter_def_set_attrs(git_filter_def *fdef)
{
	char *scan = fdef->attrdata;
	size_t i;

	for (i = 0; i < fdef->nattrs; ++i) {
		const char *name, *value;

		switch (*scan) {
		case '=':
			name = scan + 1;
			for (scan++; *scan != '='; scan++) /* find '=' */;
			*scan++ = '\0';
			value = scan;
			break;
		case '-':
			name = scan + 1; value = git_attr__false; break;
		case '+':
			name = scan + 1; value = git_attr__true;  break;
		case '!':
			name = scan + 1; value = git_attr__unset; break;
		default:
			name = scan;     value = NULL; break;
		}

		fdef->attrs[i] = name;
		fdef->attrs[i + fdef->nattrs] = value;

		scan += strlen(scan) + 1;
	}
}

static int filter_def_name_key_check(const void *key, const void *fdef)
{
	const char *name =
		fdef ? ((const git_filter_def *)fdef)->filter_name : NULL;
	return name ? git__strcmp(key, name) : -1;
}

static int filter_def_filter_key_check(const void *key, const void *fdef)
{
	const void *filter = fdef ? ((const git_filter_def *)fdef)->filter : NULL;
	return (key == filter) ? 0 : -1;
}

static int filter_registry_find(size_t *pos, const char *name)
{
	return git_vector_search2(
		pos, &git__filter_registry->filters, filter_def_name_key_check, name);
}

static git_filter_def *filter_registry_lookup(size_t *pos, const char *name)
{
	git_filter_def *fdef = NULL;

	if (!filter_registry_find(pos, name))
		fdef = git_vector_get(&git__filter_registry->filters, *pos);

	return fdef;
}

int git_filter_register(
	const char *name, git_filter *filter, int priority)
{
	git_filter_def *fdef;
	size_t nattr = 0, nmatch = 0;
	git_buf attrs = GIT_BUF_INIT;

	if (filter_registry_initialize() < 0)
		return -1;

	if (!filter_registry_find(NULL, name)) {
		giterr_set(
			GITERR_FILTER, "Attempt to reregister existing filter '%s'", name);
		return GIT_EEXISTS;
	}

	if (filter_def_scan_attrs(&attrs, &nattr, &nmatch, filter->attributes) < 0)
		return -1;

	fdef = git__calloc(
		sizeof(git_filter_def) + 2 * nattr * sizeof(char *), 1);
	GITERR_CHECK_ALLOC(fdef);

	fdef->filter_name = name;
	fdef->filter      = filter;
	fdef->priority    = priority;
	fdef->nattrs      = nattr;
	fdef->nmatches    = nmatch;
	fdef->attrdata    = git_buf_detach(&attrs);

	filter_def_set_attrs(fdef);

	if (git_vector_insert(&git__filter_registry->filters, fdef) < 0) {
		git__free(fdef->attrdata);
		git__free(fdef);
		return -1;
	}

	git_vector_sort(&git__filter_registry->filters);
	return 0;
}

int git_filter_unregister(const char *name)
{
	size_t pos;
	git_filter_def *fdef;

	/* cannot unregister default filters */
	if (!strcmp(GIT_FILTER_CRLF, name) || !strcmp(GIT_FILTER_IDENT, name)) {
		giterr_set(GITERR_FILTER, "Cannot unregister filter '%s'", name);
		return -1;
	}

	if ((fdef = filter_registry_lookup(&pos, name)) == NULL) {
		giterr_set(GITERR_FILTER, "Cannot find filter '%s' to unregister", name);
		return GIT_ENOTFOUND;
	}

	(void)git_vector_remove(&git__filter_registry->filters, pos);

	if (fdef->initialized && fdef->filter && fdef->filter->shutdown) {
		fdef->filter->shutdown(fdef->filter);
		fdef->initialized = false;
	}

	git__free(fdef->attrdata);
	git__free(fdef);

	return 0;
}

static int filter_initialize(git_filter_def *fdef)
{
	int error = 0;

	if (!fdef->initialized &&
		fdef->filter &&
		fdef->filter->initialize &&
		(error = fdef->filter->initialize(fdef->filter)) < 0)
	{
		/* auto-unregister if initialize fails */
		git_filter_unregister(fdef->filter_name);
		return error;
	}

	fdef->initialized = true;
	return 0;
}

git_filter *git_filter_lookup(const char *name)
{
	size_t pos;
	git_filter_def *fdef;

	if (filter_registry_initialize() < 0)
		return NULL;

	if ((fdef = filter_registry_lookup(&pos, name)) == NULL)
		return NULL;

	if (!fdef->initialized && filter_initialize(fdef) < 0)
		return NULL;

	return fdef->filter;
}

void git_filter_free(git_filter *filter)
{
	git__free(filter);
}

git_repository *git_filter_source_repo(const git_filter_source *src)
{
	return src->repo;
}

const char *git_filter_source_path(const git_filter_source *src)
{
	return src->path;
}

uint16_t git_filter_source_filemode(const git_filter_source *src)
{
	return src->filemode;
}

const git_oid *git_filter_source_id(const git_filter_source *src)
{
	return git_oid_iszero(&src->oid) ? NULL : &src->oid;
}

git_filter_mode_t git_filter_source_mode(const git_filter_source *src)
{
	return src->mode;
}

static int filter_list_new(
	git_filter_list **out, const git_filter_source *src)
{
	git_filter_list *fl = NULL;
	size_t pathlen = src->path ? strlen(src->path) : 0;

	fl = git__calloc(1, sizeof(git_filter_list) + pathlen + 1);
	GITERR_CHECK_ALLOC(fl);

	if (src->path)
		memcpy(fl->path, src->path, pathlen);
	fl->source.repo = src->repo;
	fl->source.path = fl->path;
	fl->source.mode = src->mode;

	*out = fl;
	return 0;
}

static int filter_list_check_attributes(
	const char ***out, git_filter_def *fdef, const git_filter_source *src)
{
	int error;
	size_t i;
	const char **strs = git__calloc(fdef->nattrs, sizeof(const char *));
	GITERR_CHECK_ALLOC(strs);

	error = git_attr_get_many(
		strs, src->repo, 0, src->path, fdef->nattrs, fdef->attrs);

	/* if no values were found but no matches are needed, it's okay! */
	if (error == GIT_ENOTFOUND && !fdef->nmatches) {
		giterr_clear();
		git__free((void *)strs);
		return 0;
	}

	for (i = 0; !error && i < fdef->nattrs; ++i) {
		const char *want = fdef->attrs[fdef->nattrs + i];
		git_attr_t want_type, found_type;

		if (!want)
			continue;

		want_type  = git_attr_value(want);
		found_type = git_attr_value(strs[i]);

		if (want_type != found_type ||
			(want_type == GIT_ATTR_VALUE_T && strcmp(want, strs[i])))
			error = GIT_ENOTFOUND;
	}

	if (error)
		git__free((void *)strs);
	else
		*out = strs;

	return error;
}

int git_filter_list_new(
	git_filter_list **out, git_repository *repo, git_filter_mode_t mode)
{
	git_filter_source src = { 0 };
	src.repo = repo;
	src.path = NULL;
	src.mode = mode;
	return filter_list_new(out, &src);
}

int git_filter_list_load(
	git_filter_list **filters,
	git_repository *repo,
	git_blob *blob, /* can be NULL */
	const char *path,
	git_filter_mode_t mode)
{
	int error = 0;
	git_filter_list *fl = NULL;
	git_filter_source src = { 0 };
	git_filter_entry *fe;
	size_t idx;
	git_filter_def *fdef;

	if (filter_registry_initialize() < 0)
		return -1;

	src.repo = repo;
	src.path = path;
	src.mode = mode;
	if (blob)
		git_oid_cpy(&src.oid, git_blob_id(blob));

	git_vector_foreach(&git__filter_registry->filters, idx, fdef) {
		const char **values = NULL;
		void *payload = NULL;

		if (!fdef || !fdef->filter)
			continue;

		if (fdef->nattrs > 0) {
			error = filter_list_check_attributes(&values, fdef, &src);
			if (error == GIT_ENOTFOUND) {
				error = 0;
				continue;
			} else if (error < 0)
				break;
		}

		if (!fdef->initialized && (error = filter_initialize(fdef)) < 0)
			break;

		if (fdef->filter->check)
			error = fdef->filter->check(
				fdef->filter, &payload, &src, values);

		git__free((void *)values);

		if (error == GIT_PASSTHROUGH)
			error = 0;
		else if (error < 0)
			break;
		else {
			if (!fl && (error = filter_list_new(&fl, &src)) < 0)
				return error;

			fe = git_array_alloc(fl->filters);
			GITERR_CHECK_ALLOC(fe);
			fe->filter  = fdef->filter;
			fe->payload = payload;
		}
	}

	if (error && fl != NULL) {
		git_array_clear(fl->filters);
		git__free(fl);
		fl = NULL;
	}

	*filters = fl;
	return error;
}

void git_filter_list_free(git_filter_list *fl)
{
	uint32_t i;

	if (!fl)
		return;

	for (i = 0; i < git_array_size(fl->filters); ++i) {
		git_filter_entry *fe = git_array_get(fl->filters, i);
		if (fe->filter->cleanup)
			fe->filter->cleanup(fe->filter, fe->payload);
	}

	git_array_clear(fl->filters);
	git__free(fl);
}

int git_filter_list_push(
	git_filter_list *fl, git_filter *filter, void *payload)
{
	int error = 0;
	size_t pos;
	git_filter_def *fdef;
	git_filter_entry *fe;

	assert(fl && filter);

	if (git_vector_search2(
			&pos, &git__filter_registry->filters,
			filter_def_filter_key_check, filter) < 0) {
		giterr_set(GITERR_FILTER, "Cannot use an unregistered filter");
		return -1;
	}

	fdef = git_vector_get(&git__filter_registry->filters, pos);

	if (!fdef->initialized && (error = filter_initialize(fdef)) < 0)
		return error;

	fe = git_array_alloc(fl->filters);
	GITERR_CHECK_ALLOC(fe);
	fe->filter  = filter;
	fe->payload = payload;

	return 0;
}

size_t git_filter_list_length(const git_filter_list *fl)
{
	return fl ? git_array_size(fl->filters) : 0;
}

static int filter_list_out_buffer_from_raw(
	git_buf *out, const void *ptr, size_t size)
{
	if (git_buf_is_allocated(out))
		git_buf_free(out);

	if (!size) {
		git_buf_init(out, 0);
	} else {
		out->ptr   = (char *)ptr;
		out->asize = 0;
		out->size  = size;
	}

	return 0;
}

int git_filter_list_apply_to_data(
	git_buf *tgt, git_filter_list *fl, git_buf *src)
{
	int error = 0;
	uint32_t i;
	git_buf *dbuffer[2], local = GIT_BUF_INIT;
	unsigned int si = 0;

	if (!fl)
		return filter_list_out_buffer_from_raw(tgt, src->ptr, src->size);

	dbuffer[0] = src;
	dbuffer[1] = tgt;

	/* if `src` buffer is reallocable, then use it, otherwise copy it */
	if (!git_buf_is_allocated(src)) {
		if (git_buf_set(&local, src->ptr, src->size) < 0)
			return -1;
		dbuffer[0] = &local;
	}

	for (i = 0; i < git_array_size(fl->filters); ++i) {
		unsigned int di = 1 - si;
		uint32_t fidx = (fl->source.mode == GIT_FILTER_TO_WORKTREE) ?
			i : git_array_size(fl->filters) - 1 - i;
		git_filter_entry *fe = git_array_get(fl->filters, fidx);

		dbuffer[di]->size = 0;

		/* Apply the filter from dbuffer[src] to the other buffer;
		 * if the filtering is canceled by the user mid-filter,
		 * we skip to the next filter without changing the source
		 * of the double buffering (so that the text goes through
		 * cleanly).
		 */

		error = fe->filter->apply(
			fe->filter, &fe->payload, dbuffer[di], dbuffer[si], &fl->source);

		if (error == GIT_PASSTHROUGH) {
			/* PASSTHROUGH means filter decided not to process the buffer */
			error = 0;
		} else if (!error) {
			git_buf_shorten(dbuffer[di], 0); /* force NUL termination */
			si = di; /* swap buffers */
		} else {
			tgt->size = 0;
			return error;
		}
	}

	/* Ensure that the output ends up in dbuffer[1] (i.e. the dest) */
	if (si != 1)
		git_buf_swap(dbuffer[0], dbuffer[1]);

	git_buf_free(&local); /* don't leak if we allocated locally */

	return 0;
}

int git_filter_list_apply_to_file(
	git_buf *out,
	git_filter_list *filters,
	git_repository *repo,
	const char *path)
{
	int error;
	const char *base = repo ? git_repository_workdir(repo) : NULL;
	git_buf abspath = GIT_BUF_INIT, raw = GIT_BUF_INIT;

	if (!(error = git_path_join_unrooted(&abspath, path, base, NULL)) &&
		!(error = git_futils_readbuffer(&raw, abspath.ptr)))
	{
		error = git_filter_list_apply_to_data(out, filters, &raw);

		git_buf_free(&raw);
	}

	git_buf_free(&abspath);
	return error;
}

int git_filter_list_apply_to_blob(
	git_buf *out,
	git_filter_list *filters,
	git_blob *blob)
{
	git_buf in = GIT_BUF_INIT;
	git_off_t rawsize = git_blob_rawsize(blob);

	if (!git__is_sizet(rawsize)) {
		giterr_set(GITERR_OS, "Blob is too large to filter");
		return -1;
	}

	in.ptr   = (char *)git_blob_rawcontent(blob);
	in.asize = 0;
	in.size  = (size_t)rawsize;

	if (filters)
		git_oid_cpy(&filters->source.oid, git_blob_id(blob));

	return git_filter_list_apply_to_data(out, filters, &in);
}
