/*
	lookup.c (02.09.09)
	exFAT file system implementation library.

	Copyright (C) 2010-2012  Andrew Nayenko

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "exfat.h"
#include <string.h>
#include <errno.h>
#include <inttypes.h>

int exfat_opendir(struct exfat* ef, struct exfat_node* dir,
		struct exfat_iterator* it)
{
	int rc;

	exfat_get_node(dir);
	it->parent = dir;
	it->current = NULL;
	rc = exfat_cache_directory(ef, dir);
	if (rc != 0)
		exfat_put_node(ef, dir);
	return rc;
}

void exfat_closedir(struct exfat* ef, struct exfat_iterator* it)
{
	exfat_put_node(ef, it->parent);
	it->parent = NULL;
	it->current = NULL;
}

struct exfat_node* exfat_readdir(struct exfat* ef, struct exfat_iterator* it)
{
	if (it->current == NULL)
		it->current = it->parent->child;
	else
		it->current = it->current->next;

	if (it->current != NULL)
		return exfat_get_node(it->current);
	else
		return NULL;
}

static int compare_char(struct exfat* ef, uint16_t a, uint16_t b)
{
	if (a >= ef->upcase_chars || b >= ef->upcase_chars)
		return (int) a - (int) b;

	return (int) le16_to_cpu(ef->upcase[a]) - (int) le16_to_cpu(ef->upcase[b]);
}

static int compare_name(struct exfat* ef, const le16_t* a, const le16_t* b)
{
	while (le16_to_cpu(*a) && le16_to_cpu(*b))
	{
		int rc = compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b));
		if (rc != 0)
			return rc;
		a++;
		b++;
	}
	return compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b));
}

static int lookup_name(struct exfat* ef, struct exfat_node* parent,
		struct exfat_node** node, const char* name, size_t n)
{
	struct exfat_iterator it;
	le16_t buffer[EXFAT_NAME_MAX + 1];
	int rc;

	*node = NULL;

	rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX, n);
	if (rc != 0)
		return rc;

	rc = exfat_opendir(ef, parent, &it);
	if (rc != 0)
		return rc;
	while ((*node = exfat_readdir(ef, &it)))
	{
		if (compare_name(ef, buffer, (*node)->name) == 0)
		{
			exfat_closedir(ef, &it);
			return 0;
		}
		exfat_put_node(ef, *node);
	}
	exfat_closedir(ef, &it);
	return -ENOENT;
}

static size_t get_comp(const char* path, const char** comp)
{
	const char* end;

	*comp = path + strspn(path, "/");				/* skip leading slashes */
	end = strchr(*comp, '/');
	if (end == NULL)
		return strlen(*comp);
	else
		return end - *comp;
}

int exfat_lookup(struct exfat* ef, struct exfat_node** node,
		const char* path)
{
	struct exfat_node* parent;
	const char* p;
	size_t n;
	int rc;

	/* start from the root directory */
	parent = *node = exfat_get_node(ef->root);
	for (p = path; (n = get_comp(p, &p)); p += n)
	{
		if (n == 1 && *p == '.')				/* skip "." component */
			continue;
		rc = lookup_name(ef, parent, node, p, n);
		if (rc != 0)
		{
			exfat_put_node(ef, parent);
			return rc;
		}
		exfat_put_node(ef, parent);
		parent = *node;
	}
	return 0;
}

static bool is_last_comp(const char* comp, size_t length)
{
	const char* p = comp + length;

	return get_comp(p, &p) == 0;
}

static bool is_allowed(const char* comp, size_t length)
{
	size_t i;

	for (i = 0; i < length; i++)
		switch (comp[i])
		{
		case 0x01 ... 0x1f:
		case '/':
		case '\\':
		case ':':
		case '*':
		case '?':
		case '"':
		case '<':
		case '>':
		case '|':
			return false;
		}
	return true;
}

int exfat_split(struct exfat* ef, struct exfat_node** parent,
		struct exfat_node** node, le16_t* name, const char* path)
{
	const char* p;
	size_t n;
	int rc;

	memset(name, 0, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
	*parent = *node = exfat_get_node(ef->root);
	for (p = path; (n = get_comp(p, &p)); p += n)
	{
		if (n == 1 && *p == '.')
			continue;
		if (is_last_comp(p, n))
		{
			if (!is_allowed(p, n))
			{
				/* contains characters that are not allowed */
				exfat_put_node(ef, *parent);
				return -ENOENT;
			}
			rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX, n);
			if (rc != 0)
			{
				exfat_put_node(ef, *parent);
				return rc;
			}

			rc = lookup_name(ef, *parent, node, p, n);
			if (rc != 0 && rc != -ENOENT)
			{
				exfat_put_node(ef, *parent);
				return rc;
			}
			return 0;
		}
		rc = lookup_name(ef, *parent, node, p, n);
		if (rc != 0)
		{
			exfat_put_node(ef, *parent);
			return rc;
		}
		exfat_put_node(ef, *parent);
		*parent = *node;
	}
	exfat_bug("impossible");
}
