/*
 * 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 "git2/config.h"
#include "git2/sys/config.h"
#include "git2/types.h"
#include "git2/repository.h"
#include "git2/index.h"
#include "git2/submodule.h"
#include "buffer.h"
#include "buf_text.h"
#include "vector.h"
#include "posix.h"
#include "config_file.h"
#include "config.h"
#include "repository.h"
#include "submodule.h"
#include "tree.h"
#include "iterator.h"
#include "path.h"
#include "index.h"

#define GIT_MODULES_FILE ".gitmodules"

static git_cvar_map _sm_update_map[] = {
	{GIT_CVAR_STRING, "checkout", GIT_SUBMODULE_UPDATE_CHECKOUT},
	{GIT_CVAR_STRING, "rebase", GIT_SUBMODULE_UPDATE_REBASE},
	{GIT_CVAR_STRING, "merge", GIT_SUBMODULE_UPDATE_MERGE},
	{GIT_CVAR_STRING, "none", GIT_SUBMODULE_UPDATE_NONE},
};

static git_cvar_map _sm_ignore_map[] = {
	{GIT_CVAR_STRING, "none", GIT_SUBMODULE_IGNORE_NONE},
	{GIT_CVAR_STRING, "untracked", GIT_SUBMODULE_IGNORE_UNTRACKED},
	{GIT_CVAR_STRING, "dirty", GIT_SUBMODULE_IGNORE_DIRTY},
	{GIT_CVAR_STRING, "all", GIT_SUBMODULE_IGNORE_ALL},
};

static kh_inline khint_t str_hash_no_trailing_slash(const char *s)
{
	khint_t h;

	for (h = 0; *s; ++s)
		if (s[1] != '\0' || *s != '/')
			h = (h << 5) - h + *s;

	return h;
}

static kh_inline int str_equal_no_trailing_slash(const char *a, const char *b)
{
	size_t alen = a ? strlen(a) : 0;
	size_t blen = b ? strlen(b) : 0;

	if (alen > 0 && a[alen - 1] == '/')
		alen--;
	if (blen > 0 && b[blen - 1] == '/')
		blen--;

	return (alen == blen && strncmp(a, b, alen) == 0);
}

__KHASH_IMPL(
	str, static kh_inline, const char *, void *, 1,
	str_hash_no_trailing_slash, str_equal_no_trailing_slash);

static int load_submodule_config(git_repository *repo);
static git_config_backend *open_gitmodules(git_repository *, bool, const git_oid *);
static int lookup_head_remote(git_buf *url, git_repository *repo);
static int submodule_get(git_submodule **, git_repository *, const char *, const char *);
static void submodule_release(git_submodule *sm, int decr);
static int submodule_load_from_index(git_repository *, const git_index_entry *);
static int submodule_load_from_head(git_repository*, const char*, const git_oid*);
static int submodule_load_from_config(const git_config_entry *, void *);
static int submodule_load_from_wd_lite(git_submodule *, const char *, void *);
static int submodule_update_config(git_submodule *, const char *, const char *, bool, bool);
static void submodule_mode_mismatch(git_repository *, const char *, unsigned int);
static int submodule_index_status(unsigned int *status, git_submodule *sm);
static int submodule_wd_status(unsigned int *status, git_submodule *sm);

static int submodule_cmp(const void *a, const void *b)
{
	return strcmp(((git_submodule *)a)->name, ((git_submodule *)b)->name);
}

static int submodule_config_key_trunc_puts(git_buf *key, const char *suffix)
{
	ssize_t idx = git_buf_rfind(key, '.');
	git_buf_truncate(key, (size_t)(idx + 1));
	return git_buf_puts(key, suffix);
}

/*
 * PUBLIC APIS
 */

int git_submodule_lookup(
	git_submodule **sm_ptr, /* NULL if user only wants to test existence */
	git_repository *repo,
	const char *name)       /* trailing slash is allowed */
{
	int error;
	khiter_t pos;

	assert(repo && name);

	if ((error = load_submodule_config(repo)) < 0)
		return error;

	pos = git_strmap_lookup_index(repo->submodules, name);

	if (!git_strmap_valid_index(repo->submodules, pos)) {
		error = GIT_ENOTFOUND;

		/* check if a plausible submodule exists at path */
		if (git_repository_workdir(repo)) {
			git_buf path = GIT_BUF_INIT;

			if (git_buf_joinpath(&path, git_repository_workdir(repo), name) < 0)
				return -1;

			if (git_path_contains_dir(&path, DOT_GIT))
				error = GIT_EEXISTS;

			git_buf_free(&path);
		}

		giterr_set(GITERR_SUBMODULE, (error == GIT_ENOTFOUND) ?
			"No submodule named '%s'" :
			"Submodule '%s' has not been added yet", name);

		return error;
	}

	if (sm_ptr)
		*sm_ptr = git_strmap_value_at(repo->submodules, pos);

	return 0;
}

int git_submodule_foreach(
	git_repository *repo,
	int (*callback)(git_submodule *sm, const char *name, void *payload),
	void *payload)
{
	int error;
	git_submodule *sm;
	git_vector seen = GIT_VECTOR_INIT;
	git_vector_set_cmp(&seen, submodule_cmp);

	assert(repo && callback);

	if ((error = load_submodule_config(repo)) < 0)
		return error;

	git_strmap_foreach_value(repo->submodules, sm, {
		/* Usually the following will not come into play - it just prevents
		 * us from issuing a callback twice for a submodule where the name
		 * and path are not the same.
		 */
		if (sm->refcount > 1) {
			if (git_vector_bsearch(NULL, &seen, sm) != GIT_ENOTFOUND)
				continue;
			if ((error = git_vector_insert(&seen, sm)) < 0)
				break;
		}

		if (callback(sm, sm->name, payload)) {
			giterr_clear();
			error = GIT_EUSER;
			break;
		}
	});

	git_vector_free(&seen);

	return error;
}

void git_submodule_config_free(git_repository *repo)
{
	git_strmap *smcfg;
	git_submodule *sm;

	assert(repo);

	smcfg = repo->submodules;
	repo->submodules = NULL;

	if (smcfg == NULL)
		return;

	git_strmap_foreach_value(smcfg, sm, {
		submodule_release(sm,1);
	});
	git_strmap_free(smcfg);
}

int git_submodule_add_setup(
	git_submodule **submodule,
	git_repository *repo,
	const char *url,
	const char *path,
	int use_gitlink)
{
	int error = 0;
	git_config_backend *mods = NULL;
	git_submodule *sm;
	git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
	git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
	git_repository *subrepo = NULL;

	assert(repo && url && path);

	/* see if there is already an entry for this submodule */

	if (git_submodule_lookup(&sm, repo, path) < 0)
		giterr_clear();
	else {
		giterr_set(GITERR_SUBMODULE,
			"Attempt to add a submodule that already exists");
		return GIT_EEXISTS;
	}

	/* resolve parameters */

	if (url[0] == '.' && (url[1] == '/' || (url[1] == '.' && url[2] == '/'))) {
		if (!(error = lookup_head_remote(&real_url, repo)))
			error = git_path_apply_relative(&real_url, url);
	} else if (strchr(url, ':') != NULL || url[0] == '/') {
		error = git_buf_sets(&real_url, url);
	} else {
		giterr_set(GITERR_SUBMODULE, "Invalid format for submodule URL");
		error = -1;
	}
	if (error)
		goto cleanup;

	/* validate and normalize path */

	if (git__prefixcmp(path, git_repository_workdir(repo)) == 0)
		path += strlen(git_repository_workdir(repo));

	if (git_path_root(path) >= 0) {
		giterr_set(GITERR_SUBMODULE, "Submodule path must be a relative path");
		error = -1;
		goto cleanup;
	}

	/* update .gitmodules */

	if ((mods = open_gitmodules(repo, true, NULL)) == NULL) {
		giterr_set(GITERR_SUBMODULE,
			"Adding submodules to a bare repository is not supported (for now)");
		return -1;
	}

	if ((error = git_buf_printf(&name, "submodule.%s.path", path)) < 0 ||
		(error = git_config_file_set_string(mods, name.ptr, path)) < 0)
		goto cleanup;

	if ((error = submodule_config_key_trunc_puts(&name, "url")) < 0 ||
		(error = git_config_file_set_string(mods, name.ptr, real_url.ptr)) < 0)
		goto cleanup;

	git_buf_clear(&name);

	/* init submodule repository and add origin remote as needed */

	error = git_buf_joinpath(&name, git_repository_workdir(repo), path);
	if (error < 0)
		goto cleanup;

	/* New style: sub-repo goes in <repo-dir>/modules/<name>/ with a
	 * gitlink in the sub-repo workdir directory to that repository
	 *
	 * Old style: sub-repo goes directly into repo/<name>/.git/
	 */

	initopt.flags = GIT_REPOSITORY_INIT_MKPATH |
		GIT_REPOSITORY_INIT_NO_REINIT;
	initopt.origin_url = real_url.ptr;

	if (git_path_exists(name.ptr) &&
		git_path_contains(&name, DOT_GIT))
	{
		/* repo appears to already exist - reinit? */
	}
	else if (use_gitlink) {
		git_buf repodir = GIT_BUF_INIT;

		error = git_buf_join_n(
			&repodir, '/', 3, git_repository_path(repo), "modules", path);
		if (error < 0)
			goto cleanup;

		initopt.workdir_path = name.ptr;
		initopt.flags |= GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;

		error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt);

		git_buf_free(&repodir);
	}
	else {
		error = git_repository_init_ext(&subrepo, name.ptr, &initopt);
	}
	if (error < 0)
		goto cleanup;

	/* add submodule to hash and "reload" it */

	if (!(error = submodule_get(&sm, repo, path, NULL)) &&
		!(error = git_submodule_reload(sm)))
		error = git_submodule_init(sm, false);

cleanup:
	if (submodule != NULL)
		*submodule = !error ? sm : NULL;

	if (mods != NULL)
		git_config_file_free(mods);
	git_repository_free(subrepo);
	git_buf_free(&real_url);
	git_buf_free(&name);

	return error;
}

int git_submodule_add_finalize(git_submodule *sm)
{
	int error;
	git_index *index;

	assert(sm);

	if ((error = git_repository_index__weakptr(&index, sm->owner)) < 0 ||
		(error = git_index_add_bypath(index, GIT_MODULES_FILE)) < 0)
		return error;

	return git_submodule_add_to_index(sm, true);
}

int git_submodule_add_to_index(git_submodule *sm, int write_index)
{
	int error;
	git_repository *repo, *sm_repo = NULL;
	git_index *index;
	git_buf path = GIT_BUF_INIT;
	git_commit *head;
	git_index_entry entry;
	struct stat st;

	assert(sm);

	repo = sm->owner;

	/* force reload of wd OID by git_submodule_open */
	sm->flags = sm->flags & ~GIT_SUBMODULE_STATUS__WD_OID_VALID;

	if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
		(error = git_buf_joinpath(
			&path, git_repository_workdir(repo), sm->path)) < 0 ||
		(error = git_submodule_open(&sm_repo, sm)) < 0)
		goto cleanup;

	/* read stat information for submodule working directory */
	if (p_stat(path.ptr, &st) < 0) {
		giterr_set(GITERR_SUBMODULE,
			"Cannot add submodule without working directory");
		error = -1;
		goto cleanup;
	}

	memset(&entry, 0, sizeof(entry));
	entry.path = sm->path;
	git_index_entry__init_from_stat(&entry, &st);

	/* calling git_submodule_open will have set sm->wd_oid if possible */
	if ((sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) == 0) {
		giterr_set(GITERR_SUBMODULE,
			"Cannot add submodule without HEAD to index");
		error = -1;
		goto cleanup;
	}
	git_oid_cpy(&entry.oid, &sm->wd_oid);

	if ((error = git_commit_lookup(&head, sm_repo, &sm->wd_oid)) < 0)
		goto cleanup;

	entry.ctime.seconds = git_commit_time(head);
	entry.ctime.nanoseconds = 0;
	entry.mtime.seconds = git_commit_time(head);
	entry.mtime.nanoseconds = 0;

	git_commit_free(head);

	/* add it */
	error = git_index_add(index, &entry);

	/* write it, if requested */
	if (!error && write_index) {
		error = git_index_write(index);

		if (!error)
			git_oid_cpy(&sm->index_oid, &sm->wd_oid);
	}

cleanup:
	git_repository_free(sm_repo);
	git_buf_free(&path);
	return error;
}

int git_submodule_save(git_submodule *submodule)
{
	int error = 0;
	git_config_backend *mods;
	git_buf key = GIT_BUF_INIT;

	assert(submodule);

	mods = open_gitmodules(submodule->owner, true, NULL);
	if (!mods) {
		giterr_set(GITERR_SUBMODULE,
			"Adding submodules to a bare repository is not supported (for now)");
		return -1;
	}

	if ((error = git_buf_printf(&key, "submodule.%s.", submodule->name)) < 0)
		goto cleanup;

	/* save values for path, url, update, ignore, fetchRecurseSubmodules */

	if ((error = submodule_config_key_trunc_puts(&key, "path")) < 0 ||
		(error = git_config_file_set_string(mods, key.ptr, submodule->path)) < 0)
		goto cleanup;

	if ((error = submodule_config_key_trunc_puts(&key, "url")) < 0 ||
		(error = git_config_file_set_string(mods, key.ptr, submodule->url)) < 0)
		goto cleanup;

	if (!(error = submodule_config_key_trunc_puts(&key, "update")) &&
		submodule->update != GIT_SUBMODULE_UPDATE_DEFAULT)
	{
		const char *val = (submodule->update == GIT_SUBMODULE_UPDATE_CHECKOUT) ?
			NULL : _sm_update_map[submodule->update].str_match;
		error = git_config_file_set_string(mods, key.ptr, val);
	}
	if (error < 0)
		goto cleanup;

	if (!(error = submodule_config_key_trunc_puts(&key, "ignore")) &&
		submodule->ignore != GIT_SUBMODULE_IGNORE_DEFAULT)
	{
		const char *val = (submodule->ignore == GIT_SUBMODULE_IGNORE_NONE) ?
			NULL : _sm_ignore_map[submodule->ignore].str_match;
		error = git_config_file_set_string(mods, key.ptr, val);
	}
	if (error < 0)
		goto cleanup;

	if ((error = submodule_config_key_trunc_puts(
			&key, "fetchRecurseSubmodules")) < 0 ||
		(error = git_config_file_set_string(
			mods, key.ptr, submodule->fetch_recurse ? "true" : "false")) < 0)
		goto cleanup;

	/* update internal defaults */

	submodule->ignore_default = submodule->ignore;
	submodule->update_default = submodule->update;
	submodule->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;

cleanup:
	if (mods != NULL)
		git_config_file_free(mods);
	git_buf_free(&key);

	return error;
}

git_repository *git_submodule_owner(git_submodule *submodule)
{
	assert(submodule);
	return submodule->owner;
}

const char *git_submodule_name(git_submodule *submodule)
{
	assert(submodule);
	return submodule->name;
}

const char *git_submodule_path(git_submodule *submodule)
{
	assert(submodule);
	return submodule->path;
}

const char *git_submodule_url(git_submodule *submodule)
{
	assert(submodule);
	return submodule->url;
}

int git_submodule_set_url(git_submodule *submodule, const char *url)
{
	assert(submodule && url);

	git__free(submodule->url);

	submodule->url = git__strdup(url);
	GITERR_CHECK_ALLOC(submodule->url);

	return 0;
}

const git_oid *git_submodule_index_id(git_submodule *submodule)
{
	assert(submodule);

	if (submodule->flags & GIT_SUBMODULE_STATUS__INDEX_OID_VALID)
		return &submodule->index_oid;
	else
		return NULL;
}

const git_oid *git_submodule_head_id(git_submodule *submodule)
{
	assert(submodule);

	if (submodule->flags & GIT_SUBMODULE_STATUS__HEAD_OID_VALID)
		return &submodule->head_oid;
	else
		return NULL;
}

const git_oid *git_submodule_wd_id(git_submodule *submodule)
{
	assert(submodule);

	if (!(submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)) {
		git_repository *subrepo;

		/* calling submodule open grabs the HEAD OID if possible */
		if (!git_submodule_open(&subrepo, submodule))
			git_repository_free(subrepo);
		else
			giterr_clear();
	}

	if (submodule->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID)
		return &submodule->wd_oid;
	else
		return NULL;
}

git_submodule_ignore_t git_submodule_ignore(git_submodule *submodule)
{
	assert(submodule);
	return submodule->ignore;
}

git_submodule_ignore_t git_submodule_set_ignore(
	git_submodule *submodule, git_submodule_ignore_t ignore)
{
	git_submodule_ignore_t old;

	assert(submodule);

	if (ignore == GIT_SUBMODULE_IGNORE_DEFAULT)
		ignore = submodule->ignore_default;

	old = submodule->ignore;
	submodule->ignore = ignore;
	return old;
}

git_submodule_update_t git_submodule_update(git_submodule *submodule)
{
	assert(submodule);
	return submodule->update;
}

git_submodule_update_t git_submodule_set_update(
	git_submodule *submodule, git_submodule_update_t update)
{
	git_submodule_update_t old;

	assert(submodule);

	if (update == GIT_SUBMODULE_UPDATE_DEFAULT)
		update = submodule->update_default;

	old = submodule->update;
	submodule->update = update;
	return old;
}

int git_submodule_fetch_recurse_submodules(
	git_submodule *submodule)
{
	assert(submodule);
	return submodule->fetch_recurse;
}

int git_submodule_set_fetch_recurse_submodules(
	git_submodule *submodule,
	int fetch_recurse_submodules)
{
	int old;

	assert(submodule);

	old = submodule->fetch_recurse;
	submodule->fetch_recurse = (fetch_recurse_submodules != 0);
	return old;
}

int git_submodule_init(git_submodule *submodule, int overwrite)
{
	int error;

	/* write "submodule.NAME.url" */

	if (!submodule->url) {
		giterr_set(GITERR_SUBMODULE,
			"No URL configured for submodule '%s'", submodule->name);
		return -1;
	}

	error = submodule_update_config(
		submodule, "url", submodule->url, overwrite != 0, false);
	if (error < 0)
		return error;

	/* write "submodule.NAME.update" if not default */

	if (submodule->update == GIT_SUBMODULE_UPDATE_CHECKOUT)
		error = submodule_update_config(
			submodule, "update", NULL, (overwrite != 0), false);
	else if (submodule->update != GIT_SUBMODULE_UPDATE_DEFAULT)
		error = submodule_update_config(
			submodule, "update",
			_sm_update_map[submodule->update].str_match,
			(overwrite != 0), false);

	return error;
}

int git_submodule_sync(git_submodule *submodule)
{
	if (!submodule->url) {
		giterr_set(GITERR_SUBMODULE,
			"No URL configured for submodule '%s'", submodule->name);
		return -1;
	}

	/* copy URL over to config only if it already exists */

	return submodule_update_config(
		submodule, "url", submodule->url, true, true);
}

int git_submodule_open(
	git_repository **subrepo,
	git_submodule *submodule)
{
	int error;
	git_buf path = GIT_BUF_INIT;
	git_repository *repo;
	const char *workdir;

	assert(submodule && subrepo);

	repo = submodule->owner;
	workdir = git_repository_workdir(repo);

	if (!workdir) {
		giterr_set(GITERR_REPOSITORY,
			"Cannot open submodule repository in a bare repo");
		return GIT_ENOTFOUND;
	}

	if ((submodule->flags & GIT_SUBMODULE_STATUS_IN_WD) == 0) {
		giterr_set(GITERR_REPOSITORY,
			"Cannot open submodule repository that is not checked out");
		return GIT_ENOTFOUND;
	}

	if (git_buf_joinpath(&path, workdir, submodule->path) < 0)
		return -1;

	error = git_repository_open(subrepo, path.ptr);

	git_buf_free(&path);

	/* if we have opened the submodule successfully, let's grab the HEAD OID */
	if (!error) {
		if (!git_reference_name_to_id(
				&submodule->wd_oid, *subrepo, GIT_HEAD_FILE))
			submodule->flags |= GIT_SUBMODULE_STATUS__WD_OID_VALID;
		else
			giterr_clear();
	}

	return error;
}

int git_submodule_reload_all(git_repository *repo)
{
	assert(repo);
	git_submodule_config_free(repo);
	return load_submodule_config(repo);
}

int git_submodule_reload(git_submodule *submodule)
{
	git_repository *repo;
	git_index *index;
	int error;
	size_t pos;
	git_tree *head;
	git_config_backend *mods;

	assert(submodule);

	/* refresh index data */

	repo = submodule->owner;
	if (git_repository_index__weakptr(&index, repo) < 0)
		return -1;

	submodule->flags = submodule->flags &
		~(GIT_SUBMODULE_STATUS_IN_INDEX |
		  GIT_SUBMODULE_STATUS__INDEX_OID_VALID);

	if (!git_index_find(&pos, index, submodule->path)) {
		const git_index_entry *entry = git_index_get_byindex(index, pos);

		if (S_ISGITLINK(entry->mode)) {
			if ((error = submodule_load_from_index(repo, entry)) < 0)
				return error;
		} else {
			submodule_mode_mismatch(
				repo, entry->path, GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE);
		}
	}

	/* refresh HEAD tree data */

	if (!(error = git_repository_head_tree(&head, repo))) {
		git_tree_entry *te;

		submodule->flags = submodule->flags &
			~(GIT_SUBMODULE_STATUS_IN_HEAD |
			  GIT_SUBMODULE_STATUS__HEAD_OID_VALID);

		if (!(error = git_tree_entry_bypath(&te, head, submodule->path))) {

			if (S_ISGITLINK(te->attr)) {
				error = submodule_load_from_head(repo, submodule->path, &te->oid);
			} else {
				submodule_mode_mismatch(
					repo, submodule->path,
					GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE);
			}

			git_tree_entry_free(te);
		}
		else if (error == GIT_ENOTFOUND) {
			giterr_clear();
			error = 0;
		}

		git_tree_free(head);
	}

	if (error < 0)
		return error;

	/* refresh config data */

	if ((mods = open_gitmodules(repo, false, NULL)) != NULL) {
		git_buf path = GIT_BUF_INIT;

		git_buf_sets(&path, "submodule\\.");
		git_buf_text_puts_escape_regex(&path, submodule->name);
		git_buf_puts(&path, ".*");

		if (git_buf_oom(&path))
			error = -1;
		else
			error = git_config_file_foreach_match(
				mods, path.ptr, submodule_load_from_config, repo);

		git_buf_free(&path);
		git_config_file_free(mods);
	}

	if (error < 0)
		return error;

	/* refresh wd data */

	submodule->flags = submodule->flags &
		~(GIT_SUBMODULE_STATUS_IN_WD | GIT_SUBMODULE_STATUS__WD_OID_VALID);

	error = submodule_load_from_wd_lite(submodule, submodule->path, NULL);

	return error;
}

int git_submodule_status(
	unsigned int *status,
	git_submodule *submodule)
{
	int error = 0;
	unsigned int status_val;

	assert(status && submodule);

	status_val = GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(submodule->flags);

	if (submodule->ignore != GIT_SUBMODULE_IGNORE_ALL) {
		if (!(error = submodule_index_status(&status_val, submodule)))
			error = submodule_wd_status(&status_val, submodule);
	}

	*status = status_val;

	return error;
}

int git_submodule_location(
	unsigned int *location_status,
	git_submodule *submodule)
{
	assert(location_status && submodule);

	*location_status = submodule->flags &
		(GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX |
		 GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_IN_WD);

	return 0;
}


/*
 * INTERNAL FUNCTIONS
 */

static git_submodule *submodule_alloc(git_repository *repo, const char *name)
{
	git_submodule *sm;

	if (!name || !strlen(name)) {
		giterr_set(GITERR_SUBMODULE, "Invalid submodule name");
		return NULL;
	}

	sm = git__calloc(1, sizeof(git_submodule));
	if (sm == NULL)
		goto fail;

	sm->path = sm->name = git__strdup(name);
	if (!sm->name)
		goto fail;

	sm->owner = repo;
	sm->refcount = 1;

	return sm;

fail:
	submodule_release(sm, 0);
	return NULL;
}

static void submodule_release(git_submodule *sm, int decr)
{
	if (!sm)
		return;

	sm->refcount -= decr;

	if (sm->refcount == 0) {
		if (sm->name != sm->path) {
			git__free(sm->path);
			sm->path = NULL;
		}

		git__free(sm->name);
		sm->name = NULL;

		git__free(sm->url);
		sm->url = NULL;

		sm->owner = NULL;

		git__free(sm);
	}
}

static int submodule_get(
	git_submodule **sm_ptr,
	git_repository *repo,
	const char *name,
	const char *alternate)
{
	git_strmap *smcfg = repo->submodules;
	khiter_t pos;
	git_submodule *sm;
	int error;

	assert(repo && name);

	pos = git_strmap_lookup_index(smcfg, name);

	if (!git_strmap_valid_index(smcfg, pos) && alternate)
		pos = git_strmap_lookup_index(smcfg, alternate);

	if (!git_strmap_valid_index(smcfg, pos)) {
		sm = submodule_alloc(repo, name);

		/* insert value at name - if another thread beats us to it, then use
		 * their record and release our own.
		 */
		pos = kh_put(str, smcfg, sm->name, &error);

		if (error < 0) {
			submodule_release(sm, 1);
			sm = NULL;
		} else if (error == 0) {
			submodule_release(sm, 1);
			sm = git_strmap_value_at(smcfg, pos);
		} else {
			git_strmap_set_value_at(smcfg, pos, sm);
		}
	} else {
		sm = git_strmap_value_at(smcfg, pos);
	}

	*sm_ptr = sm;

	return (sm != NULL) ? 0 : -1;
}

static int submodule_load_from_index(
	git_repository *repo, const git_index_entry *entry)
{
	git_submodule *sm;

	if (submodule_get(&sm, repo, entry->path, NULL) < 0)
		return -1;

	if (sm->flags & GIT_SUBMODULE_STATUS_IN_INDEX) {
		sm->flags |= GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES;
		return 0;
	}

	sm->flags |= GIT_SUBMODULE_STATUS_IN_INDEX;

	git_oid_cpy(&sm->index_oid, &entry->oid);
	sm->flags |= GIT_SUBMODULE_STATUS__INDEX_OID_VALID;

	return 0;
}

static int submodule_load_from_head(
	git_repository *repo, const char *path, const git_oid *oid)
{
	git_submodule *sm;

	if (submodule_get(&sm, repo, path, NULL) < 0)
		return -1;

	sm->flags |= GIT_SUBMODULE_STATUS_IN_HEAD;

	git_oid_cpy(&sm->head_oid, oid);
	sm->flags |= GIT_SUBMODULE_STATUS__HEAD_OID_VALID;

	return 0;
}

static int submodule_config_error(const char *property, const char *value)
{
	giterr_set(GITERR_INVALID,
		"Invalid value for submodule '%s' property: '%s'", property, value);
	return -1;
}

static int submodule_load_from_config(
	const git_config_entry *entry, void *data)
{
	git_repository *repo = data;
	git_strmap *smcfg = repo->submodules;
	const char *namestart, *property, *alternate = NULL;
	const char *key = entry->name, *value = entry->value;
	git_buf name = GIT_BUF_INIT;
	git_submodule *sm;
	bool is_path;
	int error = 0;

	if (git__prefixcmp(key, "submodule.") != 0)
		return 0;

	namestart = key + strlen("submodule.");
	property  = strrchr(namestart, '.');
	if (property == NULL)
		return 0;
	property++;
	is_path = (strcasecmp(property, "path") == 0);

	if (git_buf_set(&name, namestart, property - namestart - 1) < 0)
		return -1;

	if (submodule_get(&sm, repo, name.ptr, is_path ? value : NULL) < 0) {
		git_buf_free(&name);
		return -1;
	}

	sm->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;

	/* Only from config might we get differing names & paths.  If so, then
	 * update the submodule and insert under the alternative key.
	 */

	/* TODO: if case insensitive filesystem, then the following strcmps
	 * should be strcasecmp
	 */

	if (strcmp(sm->name, name.ptr) != 0) {
		alternate = sm->name = git_buf_detach(&name);
	} else if (is_path && value && strcmp(sm->path, value) != 0) {
		alternate = sm->path = git__strdup(value);
		if (!sm->path)
			error = -1;
	}
	if (alternate) {
		void *old_sm = NULL;
		git_strmap_insert2(smcfg, alternate, sm, old_sm, error);

		if (error >= 0)
			sm->refcount++; /* inserted under a new key */

		/* if we replaced an old module under this key, release the old one */
		if (old_sm && ((git_submodule *)old_sm) != sm) {
			submodule_release(old_sm, 1);
			/* TODO: log warning about multiple submodules with same path */
		}
	}

	git_buf_free(&name);
	if (error < 0)
		return error;

	/* TODO: Look up path in index and if it is present but not a GITLINK
	 * then this should be deleted (at least to match git's behavior)
	 */

	if (is_path)
		return 0;

	/* copy other properties into submodule entry */
	if (strcasecmp(property, "url") == 0) {
		git__free(sm->url);
		sm->url = NULL;

		if (value != NULL && (sm->url = git__strdup(value)) == NULL)
			return -1;
	}
	else if (strcasecmp(property, "update") == 0) {
		int val;
		if (git_config_lookup_map_value(
			&val, _sm_update_map, ARRAY_SIZE(_sm_update_map), value) < 0)
			return submodule_config_error("update", value);
		sm->update_default = sm->update = (git_submodule_update_t)val;
	}
	else if (strcasecmp(property, "fetchRecurseSubmodules") == 0) {
		if (git__parse_bool(&sm->fetch_recurse, value) < 0)
			return submodule_config_error("fetchRecurseSubmodules", value);
	}
	else if (strcasecmp(property, "ignore") == 0) {
		int val;
		if (git_config_lookup_map_value(
			&val, _sm_ignore_map, ARRAY_SIZE(_sm_ignore_map), value) < 0)
			return submodule_config_error("ignore", value);
		sm->ignore_default = sm->ignore = (git_submodule_ignore_t)val;
	}
	/* ignore other unknown submodule properties */

	return 0;
}

static int submodule_load_from_wd_lite(
	git_submodule *sm, const char *name, void *payload)
{
	git_repository *repo = git_submodule_owner(sm);
	git_buf path = GIT_BUF_INIT;

	GIT_UNUSED(name);
	GIT_UNUSED(payload);

	if (git_buf_joinpath(&path, git_repository_workdir(repo), sm->path) < 0)
		return -1;

	if (git_path_isdir(path.ptr))
		sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED;

	if (git_path_contains(&path, DOT_GIT))
		sm->flags |= GIT_SUBMODULE_STATUS_IN_WD;

	git_buf_free(&path);

	return 0;
}

static void submodule_mode_mismatch(
	git_repository *repo, const char *path, unsigned int flag)
{
	khiter_t pos = git_strmap_lookup_index(repo->submodules, path);

	if (git_strmap_valid_index(repo->submodules, pos)) {
		git_submodule *sm = git_strmap_value_at(repo->submodules, pos);

		sm->flags |= flag;
	}
}

static int load_submodule_config_from_index(
	git_repository *repo, git_oid *gitmodules_oid)
{
	int error;
	git_index *index;
	git_iterator *i;
	const git_index_entry *entry;

	if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
		(error = git_iterator_for_index(&i, index, 0, NULL, NULL)) < 0)
		return error;

	while (!(error = git_iterator_advance(&entry, i))) {

		if (S_ISGITLINK(entry->mode)) {
			error = submodule_load_from_index(repo, entry);
			if (error < 0)
				break;
		} else {
			submodule_mode_mismatch(
				repo, entry->path, GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE);

			if (strcmp(entry->path, GIT_MODULES_FILE) == 0)
				git_oid_cpy(gitmodules_oid, &entry->oid);
		}
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_iterator_free(i);

	return error;
}

static int load_submodule_config_from_head(
	git_repository *repo, git_oid *gitmodules_oid)
{
	int error;
	git_tree *head;
	git_iterator *i;
	const git_index_entry *entry;

	if ((error = git_repository_head_tree(&head, repo)) < 0)
		return error;

	if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0) {
		git_tree_free(head);
		return error;
	}

	while (!(error = git_iterator_advance(&entry, i))) {

		if (S_ISGITLINK(entry->mode)) {
			error = submodule_load_from_head(repo, entry->path, &entry->oid);
			if (error < 0)
				break;
		} else {
			submodule_mode_mismatch(
				repo, entry->path, GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE);

			if (strcmp(entry->path, GIT_MODULES_FILE) == 0 &&
				git_oid_iszero(gitmodules_oid))
				git_oid_cpy(gitmodules_oid, &entry->oid);
		}
	}

	if (error == GIT_ITEROVER)
		error = 0;

	git_iterator_free(i);
	git_tree_free(head);

	return error;
}

static git_config_backend *open_gitmodules(
	git_repository *repo,
	bool okay_to_create,
	const git_oid *gitmodules_oid)
{
	const char *workdir = git_repository_workdir(repo);
	git_buf path = GIT_BUF_INIT;
	git_config_backend *mods = NULL;

	if (workdir != NULL) {
		if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0)
			return NULL;

		if (okay_to_create || git_path_isfile(path.ptr)) {
			/* git_config_file__ondisk should only fail if OOM */
			if (git_config_file__ondisk(&mods, path.ptr) < 0)
				mods = NULL;
			/* open should only fail here if the file is malformed */
			else if (git_config_file_open(mods, GIT_CONFIG_LEVEL_LOCAL) < 0) {
				git_config_file_free(mods);
				mods = NULL;
			}
		}
	}

	if (!mods && gitmodules_oid && !git_oid_iszero(gitmodules_oid)) {
		/* TODO: Retrieve .gitmodules content from ODB */

		/* Should we actually do this?  Core git does not, but it means you
		 * can't really get much information about submodules on bare repos.
		 */
	}

	git_buf_free(&path);

	return mods;
}

static int load_submodule_config(git_repository *repo)
{
	int error;
	git_oid gitmodules_oid;
	git_buf path = GIT_BUF_INIT;
	git_config_backend *mods = NULL;

	if (repo->submodules)
		return 0;

	memset(&gitmodules_oid, 0, sizeof(gitmodules_oid));

	/* Submodule data is kept in a hashtable keyed by both name and path.
	 * These are usually the same, but that is not guaranteed.
	 */
	if (!repo->submodules) {
		repo->submodules = git_strmap_alloc();
		GITERR_CHECK_ALLOC(repo->submodules);
	}

	/* add submodule information from index */

	if ((error = load_submodule_config_from_index(repo, &gitmodules_oid)) < 0)
		goto cleanup;

	/* add submodule information from HEAD */

	load_submodule_config_from_head(repo, &gitmodules_oid);

	/* add submodule information from .gitmodules */

	if ((mods = open_gitmodules(repo, false, &gitmodules_oid)) != NULL)
		error = git_config_file_foreach(mods, submodule_load_from_config, repo);

	if (error != 0)
		goto cleanup;

	/* shallow scan submodules in work tree */

	if (!git_repository_is_bare(repo))
		error = git_submodule_foreach(repo, submodule_load_from_wd_lite, NULL);

cleanup:
	git_buf_free(&path);

	if (mods != NULL)
		git_config_file_free(mods);

	if (error)
		git_submodule_config_free(repo);

	return error;
}

static int lookup_head_remote(git_buf *url, git_repository *repo)
{
	int error;
	git_config *cfg;
	git_reference *head = NULL, *remote = NULL;
	const char *tgt, *scan;
	git_buf key = GIT_BUF_INIT;

	/* 1. resolve HEAD -> refs/heads/BRANCH
	 * 2. lookup config branch.BRANCH.remote -> ORIGIN
	 * 3. lookup remote.ORIGIN.url
	 */

	if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
		return error;

	if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) {
		giterr_set(GITERR_SUBMODULE,
			"Cannot resolve relative URL when HEAD cannot be resolved");
		error = GIT_ENOTFOUND;
		goto cleanup;
	}

	if (git_reference_type(head) != GIT_REF_SYMBOLIC) {
		giterr_set(GITERR_SUBMODULE,
			"Cannot resolve relative URL when HEAD is not symbolic");
		error = GIT_ENOTFOUND;
		goto cleanup;
	}

	if ((error = git_branch_upstream(&remote, head)) < 0)
		goto cleanup;

	/* remote should refer to something like refs/remotes/ORIGIN/BRANCH */

	if (git_reference_type(remote) != GIT_REF_SYMBOLIC ||
		git__prefixcmp(git_reference_symbolic_target(remote), GIT_REFS_REMOTES_DIR) != 0)
	{
		giterr_set(GITERR_SUBMODULE,
			"Cannot resolve relative URL when HEAD is not symbolic");
		error = GIT_ENOTFOUND;
		goto cleanup;
	}

	scan = tgt = git_reference_symbolic_target(remote) + strlen(GIT_REFS_REMOTES_DIR);
	while (*scan && (*scan != '/' || (scan > tgt && scan[-1] != '\\')))
		scan++; /* find non-escaped slash to end ORIGIN name */

	error = git_buf_printf(&key, "remote.%.*s.url", (int)(scan - tgt), tgt);
	if (error < 0)
		goto cleanup;

	if ((error = git_config_get_string(&tgt, cfg, key.ptr)) < 0)
		goto cleanup;

	error = git_buf_sets(url, tgt);

cleanup:
	git_buf_free(&key);
	git_reference_free(head);
	git_reference_free(remote);

	return error;
}

static int submodule_update_config(
	git_submodule *submodule,
	const char *attr,
	const char *value,
	bool overwrite,
	bool only_existing)
{
	int error;
	git_config *config;
	git_buf key = GIT_BUF_INIT;
	const char *old = NULL;

	assert(submodule);

	error = git_repository_config__weakptr(&config, submodule->owner);
	if (error < 0)
		return error;

	error = git_buf_printf(&key, "submodule.%s.%s", submodule->name, attr);
	if (error < 0)
		goto cleanup;

	if (git_config_get_string(&old, config, key.ptr) < 0)
		giterr_clear();

	if (!old && only_existing)
		goto cleanup;
	if (old && !overwrite)
		goto cleanup;
	if ((!old && !value) || (old && value && strcmp(old, value) == 0))
		goto cleanup;

	if (!value)
		error = git_config_delete_entry(config, key.ptr);
	else
		error = git_config_set_string(config, key.ptr, value);

cleanup:
	git_buf_free(&key);
	return error;
}

static int submodule_index_status(unsigned int *status, git_submodule *sm)
{
	const git_oid *head_oid  = git_submodule_head_id(sm);
	const git_oid *index_oid = git_submodule_index_id(sm);

	if (!head_oid) {
		if (index_oid)
			*status |= GIT_SUBMODULE_STATUS_INDEX_ADDED;
	}
	else if (!index_oid)
		*status |= GIT_SUBMODULE_STATUS_INDEX_DELETED;
	else if (!git_oid_equal(head_oid, index_oid))
		*status |= GIT_SUBMODULE_STATUS_INDEX_MODIFIED;

	return 0;
}

static int submodule_wd_status(unsigned int *status, git_submodule *sm)
{
	int error = 0;
	const git_oid *wd_oid, *index_oid;
	git_repository *sm_repo = NULL;

	/* open repo now if we need it (so wd_id() call won't reopen) */
	if ((sm->ignore == GIT_SUBMODULE_IGNORE_NONE ||
		 sm->ignore == GIT_SUBMODULE_IGNORE_UNTRACKED) &&
		(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) != 0)
	{
		if ((error = git_submodule_open(&sm_repo, sm)) < 0)
			return error;
	}

	index_oid = git_submodule_index_id(sm);
	wd_oid    = git_submodule_wd_id(sm);

	if (!index_oid) {
		if (wd_oid)
			*status |= GIT_SUBMODULE_STATUS_WD_ADDED;
	}
	else if (!wd_oid) {
		if ((sm->flags & GIT_SUBMODULE_STATUS__WD_SCANNED) != 0 &&
			(sm->flags & GIT_SUBMODULE_STATUS_IN_WD) == 0)
			*status |= GIT_SUBMODULE_STATUS_WD_UNINITIALIZED;
		else
			*status |= GIT_SUBMODULE_STATUS_WD_DELETED;
	}
	else if (!git_oid_equal(index_oid, wd_oid))
		*status |= GIT_SUBMODULE_STATUS_WD_MODIFIED;

	if (sm_repo != NULL) {
		git_tree *sm_head;
		git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
		git_diff_list *diff;

		/* the diffs below could be optimized with an early termination
		 * option to the git_diff functions, but for now this is sufficient
		 * (and certainly no worse that what core git does).
		 */

		/* perform head-to-index diff on submodule */

		if ((error = git_repository_head_tree(&sm_head, sm_repo)) < 0)
			return error;

		if (sm->ignore == GIT_SUBMODULE_IGNORE_NONE)
			opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;

		error = git_diff_tree_to_index(&diff, sm_repo, sm_head, NULL, &opt);

		if (!error) {
			if (git_diff_num_deltas(diff) > 0)
				*status |= GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED;

			git_diff_list_free(diff);
			diff = NULL;
		}

		git_tree_free(sm_head);

		if (error < 0)
			return error;

		/* perform index-to-workdir diff on submodule */

		error = git_diff_index_to_workdir(&diff, sm_repo, NULL, &opt);

		if (!error) {
			size_t untracked =
				git_diff_num_deltas_of_type(diff, GIT_DELTA_UNTRACKED);

			if (untracked > 0)
				*status |= GIT_SUBMODULE_STATUS_WD_UNTRACKED;

			if (git_diff_num_deltas(diff) != untracked)
				*status |= GIT_SUBMODULE_STATUS_WD_WD_MODIFIED;

			git_diff_list_free(diff);
			diff = NULL;
		}

		git_repository_free(sm_repo);
	}

	return error;
}
