/*
 * Copyright (C) 2009-2011 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */

/**
 * SECTION: cache
 * @title: Cache
 * @short_description: paths and tags (UUID/LABEL) caching
 *
 * The cache is a very simple API for working with tags (LABEL, UUID, ...) and
 * paths. The cache uses libblkid as a backend for TAGs resolution.
 *
 * All returned paths are always canonicalized.
 */
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <blkid.h>

#include "canonicalize.h"
#include "mountP.h"
#include "loopdev.h"
#include "strutils.h"

/*
 * Canonicalized (resolved) paths & tags cache
 */
#define MNT_CACHE_CHUNKSZ	128

#define MNT_CACHE_ISTAG		(1 << 1) /* entry is TAG */
#define MNT_CACHE_ISPATH	(1 << 2) /* entry is path */
#define MNT_CACHE_TAGREAD	(1 << 3) /* tag read by mnt_cache_read_tags() */

/* path cache entry */
struct mnt_cache_entry {
	char			*key;	/* search key (e.g. uncanonicalized path) */
	char			*value;	/* value (e.g. canonicalized path) */
	int			flag;
};

struct libmnt_cache {
	struct mnt_cache_entry	*ents;
	size_t			nents;
	size_t			nallocs;
	int			refcount;

	/* blkid_evaluate_tag() works in two ways:
	 *
	 * 1/ all tags are evaluated by udev /dev/disk/by-* symlinks,
	 *    then the blkid_cache is NULL.
	 *
	 * 2/ all tags are read from blkid.tab and verified by /dev
	 *    scanning, then the blkid_cache is not NULL and then it's
	 *    better to reuse the blkid_cache.
	 */
	blkid_cache		bc;

	struct libmnt_table	*mtab;
};

/**
 * mnt_new_cache:
 *
 * Returns: new struct libmnt_cache instance or NULL in case of ENOMEM error.
 */
struct libmnt_cache *mnt_new_cache(void)
{
	struct libmnt_cache *cache = calloc(1, sizeof(*cache));
	if (!cache)
		return NULL;
	DBG(CACHE, ul_debugobj(cache, "alloc"));
	cache->refcount = 1;
	return cache;
}

/**
 * mnt_free_cache:
 * @cache: pointer to struct libmnt_cache instance
 *
 * Deallocates the cache. This function does not care about reference count. Don't
 * use this function directly -- it's better to use use mnt_unref_cache().
 */
void mnt_free_cache(struct libmnt_cache *cache)
{
	size_t i;

	if (!cache)
		return;

	DBG(CACHE, ul_debugobj(cache, "free [refcount=%d]", cache->refcount));

	for (i = 0; i < cache->nents; i++) {
		struct mnt_cache_entry *e = &cache->ents[i];
		if (e->value != e->key)
			free(e->value);
		free(e->key);
	}
	free(cache->ents);
	if (cache->bc)
		blkid_put_cache(cache->bc);
	free(cache);
}

/**
 * mnt_ref_cache:
 * @cache: cache pointer
 *
 * Increments reference counter.
 */
void mnt_ref_cache(struct libmnt_cache *cache)
{
	if (cache) {
		cache->refcount++;
		/*DBG(CACHE, ul_debugobj(cache, "ref=%d", cache->refcount));*/
	}
}

/**
 * mnt_unref_cache:
 * @cache: cache pointer
 *
 * De-increments reference counter, on zero the cache is automatically
 * deallocated by mnt_free_cache().
 */
void mnt_unref_cache(struct libmnt_cache *cache)
{
	if (cache) {
		cache->refcount--;
		/*DBG(CACHE, ul_debugobj(cache, "unref=%d", cache->refcount));*/
		if (cache->refcount <= 0) {
			mnt_unref_table(cache->mtab);

			mnt_free_cache(cache);
		}
	}
}

/**
 * mnt_cache_set_targets:
 * @cache: cache pointer
 * @mtab: table with already canonicalized mountpoints
 *
 * Add to @cache reference to @mtab. This allows to avoid unnecessary paths
 * canonicalization in mnt_resolve_target().
 *
 * Returns: negative number in case of error, or 0 o success.
 */
int mnt_cache_set_targets(struct libmnt_cache *cache,
				struct libmnt_table *mtab)
{
	if (!cache)
		return -EINVAL;

	mnt_ref_table(mtab);
	mnt_unref_table(cache->mtab);
	cache->mtab = mtab;
	return 0;
}


/* note that the @key could be the same pointer as @value */
static int cache_add_entry(struct libmnt_cache *cache, char *key,
					char *value, int flag)
{
	struct mnt_cache_entry *e;

	assert(cache);
	assert(value);
	assert(key);

	if (cache->nents == cache->nallocs) {
		size_t sz = cache->nallocs + MNT_CACHE_CHUNKSZ;

		e = realloc(cache->ents, sz * sizeof(struct mnt_cache_entry));
		if (!e)
			return -ENOMEM;
		cache->ents = e;
		cache->nallocs = sz;
	}

	e = &cache->ents[cache->nents];
	e->key = key;
	e->value = value;
	e->flag = flag;
	cache->nents++;

	DBG(CACHE, ul_debugobj(cache, "add entry [%2zd] (%s): %s: %s",
			cache->nents,
			(flag & MNT_CACHE_ISPATH) ? "path" : "tag",
			value, key));
	return 0;
}

/* add tag to the cache, @devname has to be an allocated string */
static int cache_add_tag(struct libmnt_cache *cache, const char *tagname,
				const char *tagval, char *devname, int flag)
{
	size_t tksz, vlsz;
	char *key;
	int rc;

	assert(cache);
	assert(devname);
	assert(tagname);
	assert(tagval);

	/* add into cache -- cache format for TAGs is
	 *	key    = "TAG_NAME\0TAG_VALUE\0"
	 *	value  = "/dev/foo"
	 */
	tksz = strlen(tagname);
	vlsz = strlen(tagval);

	key = malloc(tksz + vlsz + 2);
	if (!key)
		return -ENOMEM;

	memcpy(key, tagname, tksz + 1);	   /* include '\0' */
	memcpy(key + tksz + 1, tagval, vlsz + 1);

	rc = cache_add_entry(cache, key, devname, flag | MNT_CACHE_ISTAG);
	if (!rc)
		return 0;

	free(key);
	return rc;
}


/*
 * Returns cached canonicalized path or NULL.
 */
static const char *cache_find_path(struct libmnt_cache *cache, const char *path)
{
	size_t i;

	if (!cache || !path)
		return NULL;

	for (i = 0; i < cache->nents; i++) {
		struct mnt_cache_entry *e = &cache->ents[i];
		if (!(e->flag & MNT_CACHE_ISPATH))
			continue;
		if (streq_paths(path, e->key))
			return e->value;
	}
	return NULL;
}

/*
 * Returns cached path or NULL.
 */
static const char *cache_find_tag(struct libmnt_cache *cache,
			const char *token, const char *value)
{
	size_t i;
	size_t tksz;

	if (!cache || !token || !value)
		return NULL;

	tksz = strlen(token);

	for (i = 0; i < cache->nents; i++) {
		struct mnt_cache_entry *e = &cache->ents[i];
		if (!(e->flag & MNT_CACHE_ISTAG))
			continue;
		if (strcmp(token, e->key) == 0 &&
		    strcmp(value, e->key + tksz + 1) == 0)
			return e->value;
	}
	return NULL;
}

static char *cache_find_tag_value(struct libmnt_cache *cache,
			const char *devname, const char *token)
{
	size_t i;

	assert(cache);
	assert(devname);
	assert(token);

	for (i = 0; i < cache->nents; i++) {
		struct mnt_cache_entry *e = &cache->ents[i];
		if (!(e->flag & MNT_CACHE_ISTAG))
			continue;
		if (strcmp(e->value, devname) == 0 &&	/* dev name */
		    strcmp(token, e->key) == 0)	/* tag name */
			return e->key + strlen(token) + 1;	/* tag value */
	}

	return NULL;
}

/**
 * mnt_cache_read_tags
 * @cache: pointer to struct libmnt_cache instance
 * @devname: path device
 *
 * Reads @devname LABEL and UUID to the @cache.
 *
 * Returns: 0 if at least one tag was added, 1 if no tag was added or
 *          negative number in case of error.
 */
int mnt_cache_read_tags(struct libmnt_cache *cache, const char *devname)
{
	blkid_probe pr;
	size_t i, ntags = 0;
	int rc;
	const char *tags[] = { "LABEL", "UUID", "TYPE", "PARTUUID", "PARTLABEL" };
	const char *blktags[] = { "LABEL", "UUID", "TYPE", "PART_ENTRY_UUID", "PART_ENTRY_NAME" };

	if (!cache || !devname)
		return -EINVAL;

	DBG(CACHE, ul_debugobj(cache, "tags for %s requested", devname));

	/* check if device is already cached */
	for (i = 0; i < cache->nents; i++) {
		struct mnt_cache_entry *e = &cache->ents[i];
		if (!(e->flag & MNT_CACHE_TAGREAD))
			continue;
		if (strcmp(e->value, devname) == 0)
			/* tags have already been read */
			return 0;
	}

	pr =  blkid_new_probe_from_filename(devname);
	if (!pr)
		return -1;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr,
			BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
			BLKID_SUBLKS_TYPE);

	blkid_probe_enable_partitions(pr, 1);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);

	rc = blkid_do_safeprobe(pr);
	if (rc)
		goto error;

	DBG(CACHE, ul_debugobj(cache, "reading tags for: %s", devname));

	for (i = 0; i < ARRAY_SIZE(tags); i++) {
		const char *data;
		char *dev;

		if (cache_find_tag_value(cache, devname, tags[i])) {
			DBG(CACHE, ul_debugobj(cache,
					"\ntag %s already cached", tags[i]));
			continue;
		}
		if (blkid_probe_lookup_value(pr, blktags[i], &data, NULL))
			continue;
		dev = strdup(devname);
		if (!dev)
			goto error;
		if (cache_add_tag(cache, tags[i], data, dev,
					MNT_CACHE_TAGREAD)) {
			free(dev);
			goto error;
		}
		ntags++;
	}

	DBG(CACHE, ul_debugobj(cache, "\tread %zd tags", ntags));
	blkid_free_probe(pr);
	return ntags ? 0 : 1;
error:
	blkid_free_probe(pr);
	return rc < 0 ? rc : -1;
}

/**
 * mnt_cache_device_has_tag:
 * @cache: paths cache
 * @devname: path to the device
 * @token: tag name (e.g "LABEL")
 * @value: tag value
 *
 * Look up @cache to check if @tag+@value are associated with @devname.
 *
 * Returns: 1 on success or 0.
 */
int mnt_cache_device_has_tag(struct libmnt_cache *cache, const char *devname,
				const char *token, const char *value)
{
	const char *path = cache_find_tag(cache, token, value);

	if (path && devname && strcmp(path, devname) == 0)
		return 1;
	return 0;
}

static int __mnt_cache_find_tag_value(struct libmnt_cache *cache,
		const char *devname, const char *token, char **data)
{
	int rc = 0;

	if (!cache || !devname || !token || !data)
		return -EINVAL;

	rc = mnt_cache_read_tags(cache, devname);
	if (rc)
		return rc;

	*data = cache_find_tag_value(cache, devname, token);
	return *data ? 0 : -1;
}

/**
 * mnt_cache_find_tag_value:
 * @cache: cache for results
 * @devname: device name
 * @token: tag name ("LABEL" or "UUID")
 *
 * Returns: LABEL or UUID for the @devname or NULL in case of error.
 */
char *mnt_cache_find_tag_value(struct libmnt_cache *cache,
		const char *devname, const char *token)
{
	char *data = NULL;

	if (__mnt_cache_find_tag_value(cache, devname, token, &data) == 0)
		return data;
	return NULL;
}

/**
 * mnt_get_fstype:
 * @devname: device name
 * @ambi: returns TRUE if probing result is ambivalent (optional argument)
 * @cache: cache for results or NULL
 *
 * Returns: filesystem type or NULL in case of error. The result has to be
 * deallocated by free() if @cache is NULL.
 */
char *mnt_get_fstype(const char *devname, int *ambi, struct libmnt_cache *cache)
{
	blkid_probe pr;
	const char *data;
	char *type = NULL;
	int rc;

	DBG(CACHE, ul_debugobj(cache, "get %s FS type", devname));

	if (cache) {
		char *val = NULL;
		rc = __mnt_cache_find_tag_value(cache, devname, "TYPE", &val);
		if (ambi)
			*ambi = rc == -2 ? TRUE : FALSE;
		return rc ? NULL : val;
	}

	/*
	 * no cache, probe directly
	 */
	pr =  blkid_new_probe_from_filename(devname);
	if (!pr)
		return NULL;

	blkid_probe_enable_superblocks(pr, 1);
	blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);

	rc = blkid_do_safeprobe(pr);

	DBG(CACHE, ul_debugobj(cache, "libblkid rc=%d", rc));

	if (!rc && !blkid_probe_lookup_value(pr, "TYPE", &data, NULL))
		type = strdup(data);

	if (ambi)
		*ambi = rc == -2 ? TRUE : FALSE;

	blkid_free_probe(pr);
	return type;
}

static char *canonicalize_path_and_cache(const char *path,
						struct libmnt_cache *cache)
{
	char *p = NULL;
	char *key = NULL;
	char *value = NULL;

	DBG(CACHE, ul_debugobj(cache, "canonicalize path %s", path));
	p = canonicalize_path(path);

	if (p && cache) {
		value = p;
		key = strcmp(path, p) == 0 ? value : strdup(path);

		if (!key || !value)
			goto error;

		if (cache_add_entry(cache, key, value,
				MNT_CACHE_ISPATH))
			goto error;
	}

	return p;
error:
	if (value != key)
		free(value);
	free(key);
	return NULL;
}

/**
 * mnt_resolve_path:
 * @path: "native" path
 * @cache: cache for results or NULL
 *
 * Converts path:
 *	- to the absolute path
 *	- /dev/dm-N to /dev/mapper/name
 *
 * Returns: absolute path or NULL in case of error. The result has to be
 * deallocated by free() if @cache is NULL.
 */
char *mnt_resolve_path(const char *path, struct libmnt_cache *cache)
{
	char *p = NULL;

	/*DBG(CACHE, ul_debugobj(cache, "resolving path %s", path));*/

	if (!path)
		return NULL;
	if (cache)
		p = (char *) cache_find_path(cache, path);
	if (!p)
		p = canonicalize_path_and_cache(path, cache);

	return p;
}

/**
 * mnt_resolve_target:
 * @path: "native" path, a potential mount point
 * @cache: cache for results or NULL.
 *
 * Like mnt_resolve_path(), unless @cache is not NULL and
 * mnt_cache_set_targets(cache, mtab) was called: if @path is found in the
 * cached @mtab and the matching entry was provided by the kernel, assume that
 * @path is already canonicalized. By avoiding a call to realpath(2) on
 * known mount points, there is a lower risk of stepping on a stale mount
 * point, which can result in an application freeze. This is also faster in
 * general, as stat(2) on a mount point is slower than on a regular file.
 *
 * Returns: absolute path or NULL in case of error. The result has to be
 * deallocated by free() if @cache is NULL.
 */
char *mnt_resolve_target(const char *path, struct libmnt_cache *cache)
{
	char *p = NULL;

	/*DBG(CACHE, ul_debugobj(cache, "resolving target %s", path));*/

	if (!cache || !cache->mtab)
		return mnt_resolve_path(path, cache);

	p = (char *) cache_find_path(cache, path);
	if (p)
		return p;
	else {
		struct libmnt_iter itr;
		struct libmnt_fs *fs = NULL;

		mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
		while (mnt_table_next_fs(cache->mtab, &itr, &fs) == 0) {

			if (!mnt_fs_is_kernel(fs)
                            || mnt_fs_is_swaparea(fs)
                            || !mnt_fs_streq_target(fs, path))
				continue;

			p = strdup(path);
			if (!p)
				return NULL;	/* ENOMEM */

			if (cache_add_entry(cache, p, p, MNT_CACHE_ISPATH)) {
				free(p);
				return NULL;	/* ENOMEM */
			}
			break;
		}
	}

	if (!p)
		p = canonicalize_path_and_cache(path, cache);
	return p;
}

/**
 * mnt_pretty_path:
 * @path: any path
 * @cache: NULL or pointer to the cache
 *
 * Converts path:
 *	- to the absolute path
 *	- /dev/dm-N to /dev/mapper/name
 *	- /dev/loopN to the loop backing filename
 *	- empty path (NULL) to 'none'
 *
 * Returns: newly allocated string with path, result always has to be deallocated
 *          by free().
 */
char *mnt_pretty_path(const char *path, struct libmnt_cache *cache)
{
	char *pretty = mnt_resolve_path(path, cache);

	if (!pretty)
		return strdup("none");

#ifdef __linux__
	/* users assume backing file name rather than /dev/loopN in
	 * output if the device has been initialized by mount(8).
	 */
	if (strncmp(pretty, "/dev/loop", 9) == 0) {
		struct loopdev_cxt lc;

		if (loopcxt_init(&lc, 0) || loopcxt_set_device(&lc, pretty))
			goto done;

		if (loopcxt_is_autoclear(&lc)) {
			char *tmp = loopcxt_get_backing_file(&lc);
			if (tmp) {
				loopcxt_deinit(&lc);
				if (!cache)
					free(pretty);	/* not cached, deallocate */
				return tmp;		/* return backing file */
			}
		}
		loopcxt_deinit(&lc);

	}
#endif

done:
	/* don't return pointer to the cache, allocate a new string */
	return cache ? strdup(pretty) : pretty;
}

/**
 * mnt_resolve_tag:
 * @token: tag name
 * @value: tag value
 * @cache: for results or NULL
 *
 * Returns: device name or NULL in case of error. The result has to be
 * deallocated by free() if @cache is NULL.
 */
char *mnt_resolve_tag(const char *token, const char *value,
		      struct libmnt_cache *cache)
{
	char *p = NULL;

	/*DBG(CACHE, ul_debugobj(cache, "resolving tag token=%s value=%s",
				token, value));*/

	if (!token || !value)
		return NULL;

	if (cache)
		p = (char *) cache_find_tag(cache, token, value);

	if (!p) {
		/* returns newly allocated string */
		p = blkid_evaluate_tag(token, value, cache ? &cache->bc : NULL);

		if (p && cache &&
		    cache_add_tag(cache, token, value, p, 0))
				goto error;
	}

	return p;
error:
	free(p);
	return NULL;
}



/**
 * mnt_resolve_spec:
 * @spec: path or tag
 * @cache: paths cache
 *
 * Returns: canonicalized path or NULL. The result has to be
 * deallocated by free() if @cache is NULL.
 */
char *mnt_resolve_spec(const char *spec, struct libmnt_cache *cache)
{
	char *cn = NULL;
	char *t = NULL, *v = NULL;

	if (!spec)
		return NULL;

	if (blkid_parse_tag_string(spec, &t, &v) == 0 && mnt_valid_tagname(t))
		cn = mnt_resolve_tag(t, v, cache);
	else
		cn = mnt_resolve_path(spec, cache);

	free(t);
	free(v);
	return cn;
}


#ifdef TEST_PROGRAM

static int test_resolve_path(struct libmnt_test *ts, int argc, char *argv[])
{
	char line[BUFSIZ];
	struct libmnt_cache *cache;

	cache = mnt_new_cache();
	if (!cache)
		return -ENOMEM;

	while(fgets(line, sizeof(line), stdin)) {
		size_t sz = strlen(line);
		char *p;

		if (sz > 0 && line[sz - 1] == '\n')
			line[sz - 1] = '\0';

		p = mnt_resolve_path(line, cache);
		printf("%s : %s\n", line, p);
	}
	mnt_unref_cache(cache);
	return 0;
}

static int test_resolve_spec(struct libmnt_test *ts, int argc, char *argv[])
{
	char line[BUFSIZ];
	struct libmnt_cache *cache;

	cache = mnt_new_cache();
	if (!cache)
		return -ENOMEM;

	while(fgets(line, sizeof(line), stdin)) {
		size_t sz = strlen(line);
		char *p;

		if (sz > 0 && line[sz - 1] == '\n')
			line[sz - 1] = '\0';

		p = mnt_resolve_spec(line, cache);
		printf("%s : %s\n", line, p);
	}
	mnt_unref_cache(cache);
	return 0;
}

static int test_read_tags(struct libmnt_test *ts, int argc, char *argv[])
{
	char line[BUFSIZ];
	struct libmnt_cache *cache;
	size_t i;

	cache = mnt_new_cache();
	if (!cache)
		return -ENOMEM;

	while(fgets(line, sizeof(line), stdin)) {
		size_t sz = strlen(line);
		char *t = NULL, *v = NULL;

		if (sz > 0 && line[sz - 1] == '\n')
			line[sz - 1] = '\0';

		if (!strcmp(line, "quit"))
			break;

		if (*line == '/') {
			if (mnt_cache_read_tags(cache, line) < 0)
				fprintf(stderr, "%s: read tags failed\n", line);

		} else if (blkid_parse_tag_string(line, &t, &v) == 0) {
			const char *cn = NULL;

			if (mnt_valid_tagname(t))
				cn = cache_find_tag(cache, t, v);
			free(t);
			free(v);

			if (cn)
				printf("%s: %s\n", line, cn);
			else
				printf("%s: not cached\n", line);
		}
	}

	for (i = 0; i < cache->nents; i++) {
		struct mnt_cache_entry *e = &cache->ents[i];
		if (!(e->flag & MNT_CACHE_ISTAG))
			continue;

		printf("%15s : %5s : %s\n", e->value, e->key,
				e->key + strlen(e->key) + 1);
	}

	mnt_unref_cache(cache);
	return 0;

}

int main(int argc, char *argv[])
{
	struct libmnt_test ts[] = {
		{ "--resolve-path", test_resolve_path, "  resolve paths from stdin" },
		{ "--resolve-spec", test_resolve_spec, "  evaluate specs from stdin" },
		{ "--read-tags", test_read_tags,       "  read devname or TAG from stdin (\"quit\" to exit)" },
		{ NULL }
	};

	return mnt_run_test(ts, argc, argv);
}
#endif
