/*
 * COPYRIGHT (c) 2006
 * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
 * ALL RIGHTS RESERVED
 *
 * Permission is granted to use, copy, create derivative works
 * and redistribute this software and such derivative works
 * for any purpose, so long as the name of The University of
 * Michigan is not used in any advertising or publicity
 * pertaining to the use of distribution of this software
 * without specific, written prior authorization.  If the
 * above copyright notice or any other identification of the
 * University of Michigan is included in any copy of any
 * portion of this software, then the disclaimer below must
 * also be included.
 *
 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGES.
 */

#include <stdlib.h>
#include <string.h>
#include <syslog.h>

#include "fsloc.h"
#include "exportfs.h"

/* Debugging tool: prints out @servers info to syslog */
static void replicas_print(struct servers *sp)
{
	int i;
	if (!sp) {
		xlog(L_NOTICE, "NULL replicas pointer");
		return;
	}
	xlog(L_NOTICE, "replicas listsize=%i", sp->h_num);
	for (i=0; i<sp->h_num; i++) {
		xlog(L_NOTICE, "    %s:%s",
		       sp->h_mp[i]->h_host, sp->h_mp[i]->h_path);
	}
}

#ifdef DEBUG
/* Called by setting 'Method = stub' in config file.  Just returns
 * some syntactically correct gibberish for testing purposes.
 */
static struct servers *method_stub(char *key)
{
	struct servers *sp;
	struct mount_point *mp;

	xlog(L_NOTICE, "called method_stub\n");
	sp = malloc(sizeof(struct servers));
	if (!sp)
		return NULL;
	mp = calloc(1, sizeof(struct mount_point));
	if (!mp) {
		free(sp);
		return NULL;
	}
	sp->h_num = 1;
	sp->h_mp[0] = mp;
	mp->h_host = strdup("stub_server");
	mp->h_path = strdup("/my/test/path");
	sp->h_referral = 1;
	return sp;
}
#endif	/* DEBUG */

/* Scan @list, which is a NULL-terminated array of strings of the
 * form path@host[+host], and return corresponding servers structure.
 */
static struct servers *parse_list(char **list)
{
	int i;
	struct servers *res;
	struct mount_point *mp;
	char *cp;

	res = malloc(sizeof(struct servers));
	if (!res)
		return NULL;
	res->h_num = 0;

	/* parse each of the answers in sucession. */
	for (i=0; list[i] && i<FSLOC_MAX_LIST; i++) {
		mp = calloc(1, sizeof(struct mount_point));
		if (!mp) {
			release_replicas(res);
			return NULL;
		}
		cp = strchr(list[i], '@');
		if ((!cp) || list[i][0] != '/') {
			xlog(L_WARNING, "invalid entry '%s'", list[i]);
			continue; /* XXX Need better error handling */
		}
		res->h_mp[i] = mp;
		res->h_num++;
		mp->h_path = strndup(list[i], cp - list[i]);
		cp++;
		mp->h_host = strdup(cp);
		/* hosts are '+' separated, kernel expects ':' separated */
		while ( (cp = strchr(mp->h_host, '+')) )
		       *cp = ':';
	}
	return res;
}

/* @data is a string of form path@host[+host][:path@host[+host]]
 */
static struct servers *method_list(char *data)
{
	char *copy, *ptr=data, *p;
	char **list;
	int i, listsize;
	struct servers *rv=NULL;
	bool v6esc = false;

	xlog(L_NOTICE, "method_list(%s)", data);
	for (ptr--, listsize=1; ptr; ptr=index(ptr, ':'), listsize++)
		ptr++;
	list = malloc(listsize * sizeof(char *));
	copy = strdup(data);
	if (copy)
		xlog(L_NOTICE, "converted to %s", copy);
	if (list && copy) {
		ptr = copy;
		for (p = ptr, i = 0; *p && i < listsize; p++) {
			if (*p == '[')
				v6esc = true;
			else if (*p == ']')
				v6esc = false;

			if (!v6esc && *p == ':') {
				*p = '\0';
				if (*ptr)
					list[i++] = ptr;
				ptr = p + 1;
			}
		}
		if (*ptr)
			list[i++] = ptr;
		list[i] = NULL;
		rv = parse_list(list);
	}
	free(copy);
	free(list);
	replicas_print(rv);
	return rv;
}

/* Returns appropriately filled struct servers, or NULL if had a problem */
struct servers *replicas_lookup(int method, char *data)
{
	struct servers *sp=NULL;
	switch(method) {
	case FSLOC_NONE:
		break;
	case FSLOC_REFER:
		sp = method_list(data);
		if (sp)
			sp->h_referral = 1;
		break;
	case FSLOC_REPLICA:
		sp = method_list(data);
		if (sp)
			sp->h_referral = 0;
		break;
#ifdef DEBUG
	case FSLOC_STUB:
		sp = method_stub(data);
		break;
#endif
	default:
		xlog(L_WARNING, "Unknown method = %i", method);
	}
	replicas_print(sp);
	return sp;
}

void release_replicas(struct servers *server)
{
	int i;

	if (!server) return;
	for (i = 0; i < server->h_num; i++) {
		free(server->h_mp[i]->h_host);
		free(server->h_mp[i]->h_path);
		free(server->h_mp[i]);
	}
	free(server);
}
