/*******************************************************************************
* Copyright (C) 2006 Intel Corp. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  - Neither the name of Intel Corp. nor the names of its
*    contributors may be used to endorse or promote products derived from this
*    software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

/**
 * @author Denis Sadykov
 */
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#include "u/libu.h"

#define FOUND_HELP ((void *)1)
/* ----------------------------------------------------------------------------
			Misc
----------------------------------------------------------------------------- */

struct tmp_buf {
	long int		lint;
	char			*ptr;
	char			**pptr;
	u_option_entry_t	*entry;
};

typedef struct tmp_help_buf {
	char		*part1;
	char		*part2;
} tmp_help_buf_t;

typedef struct help_buf {
	tmp_help_buf_t	*buf;
	unsigned int	num;
	size_t		maxlen;
} help_buf_t;

static void put_to_help_buf(help_buf_t *help_buf,
			    char count,
			    const char *format, ...)
{
	va_list			ap;
	tmp_help_buf_t		*buf = &(help_buf->buf[help_buf->num]);

	buf->part2 = NULL;
	va_start(ap, format);
	buf->part1 = u_strdup_vprintf(format, ap);
	va_end(ap);
	if (count)
		help_buf->maxlen = (strlen(buf->part1) > help_buf->maxlen) ?
				strlen(buf->part1) : help_buf->maxlen;
	help_buf->num += 1;
}

static void print_help_buf(help_buf_t *help_buf)
{
	unsigned int		i,	j;
	size_t			align;
	tmp_help_buf_t		*buf = help_buf->buf;

	for (i = 0; i < help_buf->num; i++) {
		printf("%s", buf[i].part1);
		if (buf[i].part2) {
			align = (help_buf->maxlen > 50) ?
				help_buf->maxlen + 5 - strlen(buf[i].part1) :
				50 - strlen(buf[i].part1);
			for (j = 0; j < align; j++) {
				printf(" ");
			}
			printf("%s", buf[i].part2);
		}
		printf("\n");
	}
}

static void free_help_buf(help_buf_t *help_buf)
{
	unsigned int		i;
	tmp_help_buf_t		*buf = help_buf->buf;

	for (i = 0; i < help_buf->num; i++) {
		u_free(buf[i].part1);
		if (buf[i].part2)
			u_free(buf[i].part2);
	}
}

static void print_help_header(u_option_context_t *ctx, help_buf_t *help_buf)
{
	lnode_t			*node;
	u_option_group_t	*grp;
	tmp_help_buf_t		*buf = help_buf->buf;

	put_to_help_buf(help_buf, 0, "Usage:");
	put_to_help_buf(help_buf, 0, "  %s [Option...] %s",
			ctx->prog_name, ctx->usage);
	put_to_help_buf(help_buf, 0, "");
	put_to_help_buf(help_buf, 0, "Help Options");
	put_to_help_buf(help_buf, 1, "  -?, --help");

	node = list_first(ctx->groups);
	if (node && list_next(ctx->groups, node)) {
		put_to_help_buf(help_buf, 1, "  --help-all");
		buf[help_buf->num - 1].part2 = u_strdup("Show help options");
	}
	node = list_next(ctx->groups, node);
	while (node) {
		grp = (u_option_group_t *)node->list_data;
		put_to_help_buf(help_buf, 1, "  --help-%s", grp->name);
		if (grp->help_descr) {
			buf[help_buf->num - 1].part2 =
					u_strdup(grp->help_descr);
		}
		node = list_next(ctx->groups, node);
	}
	put_to_help_buf(help_buf, 0, "");

}

static void print_help_group(u_option_group_t *group, help_buf_t *help_buf)
{
	unsigned int		i;
	tmp_help_buf_t		*buf = help_buf->buf;

	if (group->ismain) {
		put_to_help_buf(help_buf, 0, "Application Options");
	} else {
		if (group->descr)
			put_to_help_buf(help_buf, 0, "%s", group->descr);
		else
			put_to_help_buf(help_buf, 0, "%s", group->name);
	}

	for (i = 0; i < group->num_entries; i++) {
		if (group->entries[i].short_name &&
				group->entries[i].arg_descr) {
			put_to_help_buf(help_buf, 1, "  -%c, --%s=%s",
					group->entries[i].short_name,
					group->entries[i].name,
					group->entries[i].arg_descr);
		} else if (group->entries[i].short_name) {
			put_to_help_buf(help_buf, 1, "  -%c, --%s",
					group->entries[i].short_name,
					group->entries[i].name);
		} else if (group->entries[i].arg_descr){
			put_to_help_buf(help_buf, 1, "  --%s=%s",
					group->entries[i].name,
					group->entries[i].arg_descr);
		} else {
			put_to_help_buf(help_buf, 1, "  --%s",
					group->entries[i].name);
		}
			if (group->entries[i].descr) {
				buf[help_buf->num - 1].part2 =
					u_strdup_printf("%s",
						group->entries[i].descr);
			}
	}
	put_to_help_buf(help_buf, 0, "");
}

static void print_short_help(u_option_context_t *ctx)
{
	help_buf_t		help_buf;
	tmp_help_buf_t		buf[1024];
	lnode_t			*node;

	help_buf.buf = buf;
	help_buf.maxlen = 0;
	help_buf.num = 0;

	node = list_first(ctx->groups);
	print_help_header(ctx, &help_buf);
	print_help_group((u_option_group_t *)node->list_data, &help_buf);

	print_help_buf(&help_buf);
	free_help_buf(&help_buf);
}

static void print_long_help(u_option_context_t *ctx, char *hoption)
{
	lnode_t			*node,	*first;
	u_option_group_t	*grp;
	char			*help_str;
	help_buf_t		help_buf;
	tmp_help_buf_t		buf[1024];

	help_buf.buf = buf;
	help_buf.maxlen = 0;
	help_buf.num = 0;

	first = list_first(ctx->groups);
	node = list_next(ctx->groups, first);
	while (node) {
		grp = (u_option_group_t *)node->list_data;
		help_str = u_strdup_printf("help-%s", grp->name);
		if (!strncmp(hoption, help_str, strlen(help_str))) {
			u_free(help_str);
			break;
		}
		u_free(help_str);
		node = list_next(ctx->groups, node);
	}

	if (!node) {
		if (!strncmp(hoption, "help-all", strlen("help-all")) &&
				strlen(hoption) == strlen("help-all")) {
			grp = (u_option_group_t *)first->list_data;
		} else if (!strncmp(hoption, "help", strlen("help")) &&
				strlen(hoption) == strlen("help")) {
			grp = NULL;
		} else {
			return;
		}
	}

	print_help_header(ctx, &help_buf);

	if (grp == NULL) {
		grp = (u_option_group_t *)first->list_data;
		print_help_group(grp, &help_buf);
	} else if (grp == (u_option_group_t *)first->list_data) {
		node = list_next(ctx->groups, first);
		while (node) {
			grp = (u_option_group_t *)node->list_data;
			print_help_group(grp, &help_buf);
			node = list_next(ctx->groups, node);
		}
		grp = (u_option_group_t *)first->list_data;
		print_help_group(grp, &help_buf);
	} else {
		print_help_group(grp, &help_buf);
	}

	print_help_buf(&help_buf);
	free_help_buf(&help_buf);
}

static unsigned int context_get_number_entries(u_option_context_t *ctx)
{
	lnode_t			*node;
	u_option_group_t	*grp;
	unsigned int		num_entr = 0;

	if (!ctx) {
		return 0;
	}

	node = list_first(ctx->groups);
	while (node) {
		grp = (u_option_group_t *)node->list_data;
		num_entr += grp->num_entries;
		node = list_next(ctx->groups, node);
	}

	return num_entr;
}

static char fill_tmp_data(struct tmp_buf *data,
			  int *filled,
			  char *optptr,
			  char *argptr,
			  u_option_entry_t *entry,
			  u_error_t **error)
{
	int	nd;
	unsigned int	count;
	char		**pptr;
	long int	val;

	for (nd = 0; nd < *filled; nd++) {
		if (data[nd].entry == entry) {
			break;
		}
	}

	switch(entry->arg) {
	case U_OPTION_ARG_INT:
		if (!isstrdigit(argptr)) {
			u_error_new(error, 0,
				"Cannot parse integer value \'%s\' for -%s\n",
				argptr, optptr);
			return 0;
		}
		val = strtol(argptr, (char **)NULL, 10);
		if (val == LONG_MIN || val == LONG_MAX) {
			u_error_new(error, 0,
				"Integer value \'%s\'for -%s out of range\n",
				argptr, optptr);
			return 0;
		}
		data[nd].lint = val;
		break;
	case U_OPTION_ARG_STRING:
		data[nd].ptr = u_strdup(argptr);
		break;
	case  U_OPTION_ARG_STRING_ARRAY:
		count = 0;
		pptr = data[nd].pptr;
		while (pptr != NULL && pptr[count] != NULL) {
			++count;
		}
		data[nd].pptr = u_malloc(sizeof(char *) * (count + 2));
		data[nd].pptr[count] = u_strdup(argptr);
		data[nd].pptr[count + 1] = NULL;
		while (count != 0) {
			count--;
			data[nd].pptr[count] = pptr[count];
		}
		if (pptr)
			u_free(pptr);
		break;
	case U_OPTION_ARG_NONE:
		data[nd].lint = 1;
		break;
	default:
		u_error_new(error, 0, "Unknown argument data type for -%s\n",
									optptr);
		return 0;
	}

	if (nd == *filled) {
		data[nd].entry = entry;
		*filled += 1;
	}

	return 1;
}

static void free_tmp_data(struct tmp_buf *data, int nd)
{
	int	i,	count;

	for (i = 0; i < nd; i++) {
		switch (data[i].entry->arg) {
		case U_OPTION_ARG_STRING:
			if (data[i].ptr) {
				u_free(data[i].ptr);
			}
			break;
		case U_OPTION_ARG_STRING_ARRAY:
			count = 0;
			while (data[i].pptr != NULL &&
						data[i].pptr[count] != NULL) {
				u_free(data[i].pptr[count]);
					count++;
				}
			if (data[i].pptr) {
				u_free(data[i].pptr);
			}
			break;
		}
	}
}

static void get_tmp_data(struct tmp_buf *data, int nd)
{
	int			i;
	u_option_entry_t	*entry;

	for (i = 0; i < nd; i++) {
		entry = data[i].entry;
		switch (entry->arg) {
		case U_OPTION_ARG_INT:
			*(long int *)entry->arg_data = data[i].lint;
			break;
		case U_OPTION_ARG_STRING:
			*(char **)entry->arg_data = data[i].ptr;
			break;
		case U_OPTION_ARG_STRING_ARRAY:
			*(char ***)entry->arg_data = data[i].pptr;
			break;
		case U_OPTION_ARG_NONE:
			*(char *)entry->arg_data = (char)data[i].lint;
		}
	}
}

static u_option_entry_t* find_long_opt(u_option_context_t *ctx, char *option)
{
	lnode_t			*node;
	u_option_group_t	*grp;
	unsigned int			e;
	size_t			nlen;

	if (!ctx) {
		return NULL;
	}

	if (!strncmp(option, "help", strlen("help")) ) {
		if (ctx->mode & U_OPTION_CONTEXT_HELP_ENABLED) {
			print_long_help(ctx, option);
                  return FOUND_HELP;
		}
	}

	node = list_first(ctx->groups);
	while (node) {
		grp = (u_option_group_t *)node->list_data;

		for (e = 0; e < grp->num_entries; e++) {
			nlen = strlen(grp->entries[e].name);

			if (!strncmp(option, grp->entries[e].name, nlen)) {
				if (strlen(option) != nlen &&
						*(option + nlen) != '=') {
					continue;
				}
				return &(grp->entries[e]);
			}
		}
		node = list_next(ctx->groups, node);
	}

	return NULL;
}

static u_option_entry_t* find_short_opt(u_option_context_t *ctx, char option)
{
	lnode_t			*node;
	u_option_group_t	*grp;
	unsigned int			e;

	if (!ctx) {
		return NULL;
	}

	if (option == '?') {
		if (ctx->mode & U_OPTION_CONTEXT_HELP_ENABLED) {
			print_short_help(ctx);
                  return FOUND_HELP;
		}
	}

	node = list_first(ctx->groups);
	while (node) {
		grp = (u_option_group_t *)node->list_data;

		for (e = 0; e < grp->num_entries; e++) {
			if (option == grp->entries[e].short_name) {
				return &(grp->entries[e]);
			}
		}
		node = list_next(ctx->groups, node);
	}

	return NULL;
}

/* ----------------------------------------------------------------------------
			Group
----------------------------------------------------------------------------- */

u_option_group_t* u_option_group_new(const char *name,
				     const char *descr,
				     const char *help_descr)
{
	u_option_group_t	*grp;

	grp = u_zalloc(sizeof(u_option_group_t));

	if (name) {
		grp->name = u_strdup(name);
	}

	if (descr) {
		grp->descr = u_strdup(descr);
	}

	if (help_descr) {
		grp->help_descr = u_strdup(help_descr);
	}

	return grp;
}

void u_option_group_free(u_option_group_t *group)
{
	if (!group)
		return;

	if (group->name)
		u_free(group->name);
	if (group->descr)
		u_free(group->descr);
	if(group->help_descr)
		u_free(group->help_descr);
    u_free(group);
}

void u_option_group_add_entries(u_option_group_t *group,
				u_option_entry_t *entries)
{
	unsigned int	i;

	if (!group || !entries) {
		return;
	}

	for (i = 0; entries[i].name; i++);
	group->entries = entries;
	group->num_entries = i;

}

/* ----------------------------------------------------------------------------
			Context
----------------------------------------------------------------------------- */

u_option_context_t* u_option_context_new(const char *usage)
{
	u_option_context_t	*ctx;

	ctx = (u_option_context_t *) u_zalloc(sizeof(u_option_context_t));

	if (usage) {
		ctx->usage = u_strdup(usage);
	}

	ctx->groups = list_create(LISTCOUNT_T_MAX);


	ctx->mode |= U_OPTION_CONTEXT_HELP_ENABLED;

	return ctx;
}

void u_option_context_free(u_option_context_t *ctx)
{
	lnode_t		*node,	*tmp;

	if (!ctx)
		return;

	node = list_first(ctx->groups);
	while (node) {
		tmp = list_next(ctx->groups, node);
		u_option_group_free((u_option_group_t *)node->list_data);
		list_delete (ctx->groups, node);
		lnode_destroy(node);
		node = tmp;
	}
	list_destroy(ctx->groups);

	if (ctx->usage)
		u_free(ctx->usage);

	if (ctx->prog_name)
		u_free(ctx->prog_name);

	u_free(ctx);
}

void u_option_context_add_group(u_option_context_t *ctx,
				u_option_group_t *group)
{
	lnode_t		*node;

	if (!ctx || !group)
		return;

	node = lnode_create((void *)group);
	list_append(ctx->groups, node);
}

void u_option_context_add_main_entries(u_option_context_t *ctx,
				       u_option_entry_t *options,
				       const char *name)
{
	u_option_group_t	*grp;
	lnode_t			*node;

	if (!ctx || !options) {
		return;
	}

	grp = u_option_group_new(name, NULL, NULL);
	u_option_group_add_entries(grp, options);
	grp->ismain = 1;
	node = lnode_create((void *)grp);
	list_prepend(ctx->groups, node);
}

void u_option_context_set_ignore_unknown_options(u_option_context_t *ctx,
						 char ignore)
{
	if (!ctx)
		return;

	if (ignore == 1)
		ctx->mode |= U_OPTION_CONTEXT_IGNORE_UNKNOWN;
	else
		ctx->mode &= ~U_OPTION_CONTEXT_IGNORE_UNKNOWN;

}

void u_option_context_set_help_enabled(u_option_context_t *ctx,
					char help_enabled)
{
	if (!ctx)
		return;

	if (help_enabled == 1)
		ctx->mode |= U_OPTION_CONTEXT_HELP_ENABLED;
	else
		ctx->mode &= ~U_OPTION_CONTEXT_HELP_ENABLED;

}

/* ----------------------------------------------------------------------------
			Parse
 * return 0 on error
 * return 1 on ok
 * return 2 on help
----------------------------------------------------------------------------- */

char u_option_context_parse(u_option_context_t *ctx,
			    int *argc,
			    char ***argv,
			    u_error_t **error)
{
	char		**tmp_argv,		**largv;
	int		arg_ind = 0,		noopt = 0;
	char		*optptr = NULL,		*argptr = NULL;
	char		next_shopt = '\0';
	int		nd = 0;
	size_t		nlen;
	int		i,	j;
	char		retval = 0;

	u_option_entry_t	*found=NULL;
	struct tmp_buf		*tmp_data;

	if (!ctx)
		return 0;

	tmp_argv = u_zalloc(sizeof(char *) * (*argc));
	largv = u_zalloc(sizeof(char *) * (*argc));

	optptr = (*argv)[0];
	while (*optptr != '\0') {
		if (*optptr == '/')
			argptr = optptr;
		optptr++;
	}
	if (argptr) {
		ctx->prog_name = u_strdup(argptr + 1);
	} else {
		ctx->prog_name = u_strdup((*argv)[0]);
	}

	for (i = 1; i < *argc; i++) {
		largv[i] = strdup((*argv)[i]);
	}

	tmp_data = u_zalloc(sizeof(struct tmp_buf) *
					context_get_number_entries(ctx));

	for(i = 1; i < *argc;) {
		if (*largv[i] != '-') {
			tmp_argv[noopt] = largv[i];
			noopt++;
			goto cont;
		}

		argptr = NULL;
		if (next_shopt != '\0') {
			optptr += 1;
			*optptr = next_shopt;
			next_shopt = '\0';
		} else {
			optptr = largv[i] + 1;
		}
		if (*optptr == '-' && optptr == largv[i] + 1) {
			found = find_long_opt(ctx, optptr + 1);
                        if (found == FOUND_HELP) {
                          goto ret;
                        }
                        else if (found) {
				nlen = strlen(found->name);
				if (strlen(optptr + 1) != nlen) {
					argptr = optptr + nlen + 2;
					*(optptr + 1 + nlen) = '\0';
				} else {
					if (i + 1 < *argc) {
						argptr = largv[i + 1];
						arg_ind++;
					}
				}
			}
		} else {
			found = find_short_opt(ctx, *optptr);
                        if (found == FOUND_HELP) {
                          goto ret;
                        }
			else if (found) {
				if (arg_ind + i + 1 < *argc) {
					arg_ind++;
					argptr = largv[arg_ind + i];
				}
				next_shopt = *(optptr + 1);
				*(optptr + 1) = '\0';
			}
		}

		if (!found) {
			u_error_new(error, 0,
				"Unknown option %s\n", (*argv)[i]);
			goto ret;
		}

		if (found->arg == U_OPTION_ARG_NONE) {
			if (argptr) {
				arg_ind--;
				argptr = NULL;
			}
			if (found->arg_data) {
				if (!fill_tmp_data(tmp_data, &nd, NULL,
							NULL, found, error)) {
					goto ret;
				}
			}
			goto cont;
		}

		if (argptr == NULL) {
			u_error_new(error, 0,
				"Missing argument for -%s\n", optptr);
			goto ret;
		}

		if (found->arg_data == NULL) {
			goto cont;
		}

		if (!fill_tmp_data(tmp_data, &nd, optptr,
					argptr, found, error)) {
			goto ret;
		}
  cont:
		if (next_shopt == '\0') {
			i = (argptr == largv[i + arg_ind] || !argptr) ?
						i + arg_ind + 1 : i + 1;
			arg_ind = 0;
		}
	}
  ret:
		if (*error) {
			free_tmp_data(tmp_data, nd);
		} else {
			for (i = 1; i < *argc; i++) {
				for (j = 0; j < noopt; j++) {
					if (!strcmp((*argv)[i], tmp_argv[j])) {
						(*argv)[j + 1] = (*argv)[i];
						break;
					}
				}
			}
			get_tmp_data(tmp_data, nd);
                        retval = (found == FOUND_HELP) ? 2 : 1;
		}
		for (i = 1; i < *argc; i++)
			u_free(largv[i]);
		*argc = noopt + 1;
		u_free(largv);
		u_free(tmp_argv);
		u_free(tmp_data);

	return retval;
}
