#include "cache.h"

/*
 * Do not use this for inspecting *tracked* content.  When path is a
 * symlink to a directory, we do not want to say it is a directory when
 * dealing with tracked content in the working tree.
 */
int is_directory(const char *path)
{
	struct stat st;
	return (!stat(path, &st) && S_ISDIR(st.st_mode));
}

/* removes the last path component from 'path' except if 'path' is root */
static void strip_last_component(struct strbuf *path)
{
	size_t offset = offset_1st_component(path->buf);
	size_t len = path->len;

	/* Find start of the last component */
	while (offset < len && !is_dir_sep(path->buf[len - 1]))
		len--;
	/* Skip sequences of multiple path-separators */
	while (offset < len && is_dir_sep(path->buf[len - 1]))
		len--;

	strbuf_setlen(path, len);
}

/* get (and remove) the next component in 'remaining' and place it in 'next' */
static void get_next_component(struct strbuf *next, struct strbuf *remaining)
{
	char *start = NULL;
	char *end = NULL;

	strbuf_reset(next);

	/* look for the next component */
	/* Skip sequences of multiple path-separators */
	for (start = remaining->buf; is_dir_sep(*start); start++)
		; /* nothing */
	/* Find end of the path component */
	for (end = start; *end && !is_dir_sep(*end); end++)
		; /* nothing */

	strbuf_add(next, start, end - start);
	/* remove the component from 'remaining' */
	strbuf_remove(remaining, 0, end - remaining->buf);
}

/* copies root part from remaining to resolved, canonicalizing it on the way */
static void get_root_part(struct strbuf *resolved, struct strbuf *remaining)
{
	int offset = offset_1st_component(remaining->buf);

	strbuf_reset(resolved);
	strbuf_add(resolved, remaining->buf, offset);
#ifdef GIT_WINDOWS_NATIVE
	convert_slashes(resolved->buf);
#endif
	strbuf_remove(remaining, 0, offset);
}

/* We allow "recursive" symbolic links. Only within reason, though. */
#ifndef MAXSYMLINKS
#define MAXSYMLINKS 32
#endif

/*
 * If set, any number of trailing components may be missing; otherwise, only one
 * may be.
 */
#define REALPATH_MANY_MISSING (1 << 0)
/* Should we die if there's an error? */
#define REALPATH_DIE_ON_ERROR (1 << 1)

static char *strbuf_realpath_1(struct strbuf *resolved, const char *path,
			       int flags)
{
	struct strbuf remaining = STRBUF_INIT;
	struct strbuf next = STRBUF_INIT;
	struct strbuf symlink = STRBUF_INIT;
	char *retval = NULL;
	int num_symlinks = 0;
	struct stat st;

	if (!*path) {
		if (flags & REALPATH_DIE_ON_ERROR)
			die("The empty string is not a valid path");
		else
			goto error_out;
	}

	strbuf_addstr(&remaining, path);
	get_root_part(resolved, &remaining);

	if (!resolved->len) {
		/* relative path; can use CWD as the initial resolved path */
		if (strbuf_getcwd(resolved)) {
			if (flags & REALPATH_DIE_ON_ERROR)
				die_errno("unable to get current working directory");
			else
				goto error_out;
		}
	}

	/* Iterate over the remaining path components */
	while (remaining.len > 0) {
		get_next_component(&next, &remaining);

		if (next.len == 0) {
			continue; /* empty component */
		} else if (next.len == 1 && !strcmp(next.buf, ".")) {
			continue; /* '.' component */
		} else if (next.len == 2 && !strcmp(next.buf, "..")) {
			/* '..' component; strip the last path component */
			strip_last_component(resolved);
			continue;
		}

		/* append the next component and resolve resultant path */
		if (!is_dir_sep(resolved->buf[resolved->len - 1]))
			strbuf_addch(resolved, '/');
		strbuf_addbuf(resolved, &next);

		if (lstat(resolved->buf, &st)) {
			/* error out unless this was the last component */
			if (errno != ENOENT ||
			   (!(flags & REALPATH_MANY_MISSING) && remaining.len)) {
				if (flags & REALPATH_DIE_ON_ERROR)
					die_errno("Invalid path '%s'",
						  resolved->buf);
				else
					goto error_out;
			}
		} else if (S_ISLNK(st.st_mode)) {
			ssize_t len;
			strbuf_reset(&symlink);

			if (num_symlinks++ > MAXSYMLINKS) {
				errno = ELOOP;

				if (flags & REALPATH_DIE_ON_ERROR)
					die("More than %d nested symlinks "
					    "on path '%s'", MAXSYMLINKS, path);
				else
					goto error_out;
			}

			len = strbuf_readlink(&symlink, resolved->buf,
					      st.st_size);
			if (len < 0) {
				if (flags & REALPATH_DIE_ON_ERROR)
					die_errno("Invalid symlink '%s'",
						  resolved->buf);
				else
					goto error_out;
			}

			if (is_absolute_path(symlink.buf)) {
				/* absolute symlink; set resolved to root */
				get_root_part(resolved, &symlink);
			} else {
				/*
				 * relative symlink
				 * strip off the last component since it will
				 * be replaced with the contents of the symlink
				 */
				strip_last_component(resolved);
			}

			/*
			 * if there are still remaining components to resolve
			 * then append them to symlink
			 */
			if (remaining.len) {
				strbuf_addch(&symlink, '/');
				strbuf_addbuf(&symlink, &remaining);
			}

			/*
			 * use the symlink as the remaining components that
			 * need to be resolved
			 */
			strbuf_swap(&symlink, &remaining);
		}
	}

	retval = resolved->buf;

error_out:
	strbuf_release(&remaining);
	strbuf_release(&next);
	strbuf_release(&symlink);

	if (!retval)
		strbuf_reset(resolved);

	return retval;
}

/*
 * Return the real path (i.e., absolute path, with symlinks resolved
 * and extra slashes removed) equivalent to the specified path.  (If
 * you want an absolute path but don't mind links, use
 * absolute_path().)  Places the resolved realpath in the provided strbuf.
 *
 * The directory part of path (i.e., everything up to the last
 * dir_sep) must denote a valid, existing directory, but the last
 * component need not exist.  If die_on_error is set, then die with an
 * informative error message if there is a problem.  Otherwise, return
 * NULL on errors (without generating any output).
 */
char *strbuf_realpath(struct strbuf *resolved, const char *path,
		      int die_on_error)
{
	return strbuf_realpath_1(resolved, path,
				 die_on_error ? REALPATH_DIE_ON_ERROR : 0);
}

/*
 * Just like strbuf_realpath, but allows an arbitrary number of path
 * components to be missing.
 */
char *strbuf_realpath_forgiving(struct strbuf *resolved, const char *path,
				int die_on_error)
{
	return strbuf_realpath_1(resolved, path,
				 ((die_on_error ? REALPATH_DIE_ON_ERROR : 0) |
				  REALPATH_MANY_MISSING));
}

char *real_pathdup(const char *path, int die_on_error)
{
	struct strbuf realpath = STRBUF_INIT;
	char *retval = NULL;

	if (strbuf_realpath(&realpath, path, die_on_error))
		retval = strbuf_detach(&realpath, NULL);

	strbuf_release(&realpath);

	return retval;
}

/*
 * Use this to get an absolute path from a relative one. If you want
 * to resolve links, you should use strbuf_realpath.
 */
const char *absolute_path(const char *path)
{
	static struct strbuf sb = STRBUF_INIT;
	strbuf_reset(&sb);
	strbuf_add_absolute_path(&sb, path);
	return sb.buf;
}

char *absolute_pathdup(const char *path)
{
	struct strbuf sb = STRBUF_INIT;
	strbuf_add_absolute_path(&sb, path);
	return strbuf_detach(&sb, NULL);
}

char *prefix_filename(const char *pfx, const char *arg)
{
	struct strbuf path = STRBUF_INIT;
	size_t pfx_len = pfx ? strlen(pfx) : 0;

	if (!pfx_len)
		; /* nothing to prefix */
	else if (is_absolute_path(arg))
		pfx_len = 0;
	else
		strbuf_add(&path, pfx, pfx_len);

	strbuf_addstr(&path, arg);
#ifdef GIT_WINDOWS_NATIVE
	convert_slashes(path.buf + pfx_len);
#endif
	return strbuf_detach(&path, NULL);
}
