/*
 * 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 "config.h"

#include "config_backend.h"
#include "config_parse.h"
#include "config_entries.h"

typedef struct {
	git_config_backend parent;
	git_config_entries *entries;
	git_buf cfg;
} config_memory_backend;

typedef struct {
	git_config_entries *entries;
	git_config_level_t level;
} config_memory_parse_data;

static int config_error_readonly(void)
{
	git_error_set(GIT_ERROR_CONFIG, "this backend is read-only");
	return -1;
}

static int read_variable_cb(
	git_config_parser *reader,
	const char *current_section,
	const char *var_name,
	const char *var_value,
	const char *line,
	size_t line_len,
	void *payload)
{
	config_memory_parse_data *parse_data = (config_memory_parse_data *) payload;
	git_buf buf = GIT_BUF_INIT;
	git_config_entry *entry;
	const char *c;
	int result;

	GIT_UNUSED(reader);
	GIT_UNUSED(line);
	GIT_UNUSED(line_len);

	if (current_section) {
		/* TODO: Once warnings land, we should likely warn
		 * here. Git appears to warn in most cases if it sees
		 * un-namespaced config options.
		 */
		git_buf_puts(&buf, current_section);
		git_buf_putc(&buf, '.');
	}

	for (c = var_name; *c; c++)
		git_buf_putc(&buf, git__tolower(*c));

	if (git_buf_oom(&buf))
		return -1;

	entry = git__calloc(1, sizeof(git_config_entry));
	GIT_ERROR_CHECK_ALLOC(entry);
	entry->name = git_buf_detach(&buf);
	entry->value = var_value ? git__strdup(var_value) : NULL;
	entry->level = parse_data->level;
	entry->include_depth = 0;

	if ((result = git_config_entries_append(parse_data->entries, entry)) < 0)
		return result;

	return result;
}

static int config_memory_open(git_config_backend *backend, git_config_level_t level, const git_repository *repo)
{
	config_memory_backend *memory_backend = (config_memory_backend *) backend;
	git_config_parser parser = GIT_PARSE_CTX_INIT;
	config_memory_parse_data parse_data;
	int error;

	GIT_UNUSED(repo);

	if ((error = git_config_parser_init(&parser, "in-memory", memory_backend->cfg.ptr,
					    memory_backend->cfg.size)) < 0)
		goto out;
	parse_data.entries = memory_backend->entries;
	parse_data.level = level;

	if ((error = git_config_parse(&parser, NULL, read_variable_cb, NULL, NULL, &parse_data)) < 0)
		goto out;

out:
	git_config_parser_dispose(&parser);
	return error;
}

static int config_memory_get(git_config_backend *backend, const char *key, git_config_entry **out)
{
	config_memory_backend *memory_backend = (config_memory_backend *) backend;
	return git_config_entries_get(out, memory_backend->entries, key);
}

static int config_memory_iterator(
	git_config_iterator **iter,
	git_config_backend *backend)
{
	config_memory_backend *memory_backend = (config_memory_backend *) backend;
	git_config_entries *entries;
	int error;

	if ((error = git_config_entries_dup(&entries, memory_backend->entries)) < 0)
		goto out;

	if ((error = git_config_entries_iterator_new(iter, entries)) < 0)
		goto out;

out:
	/* Let iterator delete duplicated entries when it's done */
	git_config_entries_free(entries);
	return error;
}

static int config_memory_set(git_config_backend *backend, const char *name, const char *value)
{
	GIT_UNUSED(backend);
	GIT_UNUSED(name);
	GIT_UNUSED(value);
	return config_error_readonly();
}

static int config_memory_set_multivar(
	git_config_backend *backend, const char *name, const char *regexp, const char *value)
{
	GIT_UNUSED(backend);
	GIT_UNUSED(name);
	GIT_UNUSED(regexp);
	GIT_UNUSED(value);
	return config_error_readonly();
}

static int config_memory_delete(git_config_backend *backend, const char *name)
{
	GIT_UNUSED(backend);
	GIT_UNUSED(name);
	return config_error_readonly();
}

static int config_memory_delete_multivar(git_config_backend *backend, const char *name, const char *regexp)
{
	GIT_UNUSED(backend);
	GIT_UNUSED(name);
	GIT_UNUSED(regexp);
	return config_error_readonly();
}

static int config_memory_lock(git_config_backend *backend)
{
	GIT_UNUSED(backend);
	return config_error_readonly();
}

static int config_memory_unlock(git_config_backend *backend, int success)
{
	GIT_UNUSED(backend);
	GIT_UNUSED(success);
	return config_error_readonly();
}

static void config_memory_free(git_config_backend *_backend)
{
	config_memory_backend *backend = (config_memory_backend *)_backend;

	if (backend == NULL)
		return;

	git_config_entries_free(backend->entries);
	git_buf_dispose(&backend->cfg);
	git__free(backend);
}

int git_config_backend_from_string(git_config_backend **out, const char *cfg, size_t len)
{
	config_memory_backend *backend;

	backend = git__calloc(1, sizeof(config_memory_backend));
	GIT_ERROR_CHECK_ALLOC(backend);

	if (git_config_entries_new(&backend->entries) < 0) {
		git__free(backend);
		return -1;
	}

	if (git_buf_set(&backend->cfg, cfg, len) < 0) {
		git_config_entries_free(backend->entries);
		git__free(backend);
		return -1;
	}

	backend->parent.version = GIT_CONFIG_BACKEND_VERSION;
	backend->parent.readonly = 1;
	backend->parent.open = config_memory_open;
	backend->parent.get = config_memory_get;
	backend->parent.set = config_memory_set;
	backend->parent.set_multivar = config_memory_set_multivar;
	backend->parent.del = config_memory_delete;
	backend->parent.del_multivar = config_memory_delete_multivar;
	backend->parent.iterator = config_memory_iterator;
	backend->parent.lock = config_memory_lock;
	backend->parent.unlock = config_memory_unlock;
	backend->parent.snapshot = git_config_backend_snapshot;
	backend->parent.free = config_memory_free;

	*out = (git_config_backend *)backend;

	return 0;
}
