/*
 * Functions used to parse typed argument lists
 *
 * Copyright 2012 Willy Tarreau <w@1wt.eu>
 *
 * 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
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <haproxy/arg.h>
#include <haproxy/chunk.h>
#include <haproxy/global.h>
#include <haproxy/regex.h>
#include <haproxy/tools.h>

const char *arg_type_names[ARGT_NBTYPES] = {
	[ARGT_STOP] = "end of arguments",
	[ARGT_SINT] = "integer",
	[ARGT_STR]  = "string",
	[ARGT_IPV4] = "IPv4 address",
	[ARGT_MSK4] = "IPv4 mask",
	[ARGT_IPV6] = "IPv6 address",
	[ARGT_MSK6] = "IPv6 mask",
	[ARGT_TIME] = "delay",
	[ARGT_SIZE] = "size",
	[ARGT_FE]   = "frontend",
	[ARGT_BE]   = "backend",
	[ARGT_TAB]  = "table",
	[ARGT_SRV]  = "server",
	[ARGT_USR]  = "user list",
	[ARGT_MAP]  = "map",
	[ARGT_REG]  = "regex",
	[ARGT_VAR]  = "variable",
	[ARGT_PBUF_FNUM] = "Protocol buffers field number",
	/* Unassigned types must never happen. Better crash during parsing if they do. */
};

/* This dummy arg list may be used by default when no arg is found, it helps
 * parsers by removing pointer checks.
 */
struct arg empty_arg_list[ARGM_NBARGS] = { };

/* This function clones a struct arg_list template into a new one which is
 * returned.
 */
struct arg_list *arg_list_clone(const struct arg_list *orig)
{
	struct arg_list *new;

	if ((new = calloc(1, sizeof(*new))) != NULL) {
		/* ->list will be set by the caller when inserting the element.
		 * ->arg and ->arg_pos will be set by the caller.
		 */
		new->ctx = orig->ctx;
		new->kw = orig->kw;
		new->conv = orig->conv;
		new->file = orig->file;
		new->line = orig->line;
	}
	return new;
}

/* This function clones a struct <arg_list> template into a new one which is
 * set to point to arg <arg> at pos <pos>, and which is returned if the caller
 * wants to apply further changes.
 */
struct arg_list *arg_list_add(struct arg_list *orig, struct arg *arg, int pos)
{
	struct arg_list *new;

	new = arg_list_clone(orig);
	if (new) {
		new->arg = arg;
		new->arg_pos = pos;
		LIST_APPEND(&orig->list, &new->list);
	}
	return new;
}

/* This function builds an argument list from a config line, and stops at the
 * first non-matching character, which is pointed to in <end_ptr>. A valid arg
 * list starts with an opening parenthesis '(', contains a number of comma-
 * delimited words, and ends with the closing parenthesis ')'. An empty list
 * (with or without the parenthesis) will lead to a valid empty argument if the
 * keyword has a mandatory one. The function returns the number of arguments
 * emitted, or <0 in case of any error. Everything needed it automatically
 * allocated. A pointer to an error message might be returned in err_msg if not
 * NULL, in which case it would be allocated and the caller will have to check
 * it and free it. The output arg list is returned in argp which must be valid.
 * The returned array is always terminated by an arg of type ARGT_STOP (0),
 * unless the mask indicates that no argument is supported. Unresolved arguments
 * are appended to arg list <al>, which also serves as a template to create new
 * entries. The mask is composed of a number of mandatory arguments in its lower
 * ARGM_BITS bits, and a concatenation of each argument type in each subsequent
 * ARGT_BITS-bit sblock. If <err_msg> is not NULL, it must point to a freeable
 * or NULL pointer. The caller is expected to restart the parsing from the new
 * pointer set in <end_ptr>, which is the first character considered as not
 * being part of the arg list. The input string ends on the first between <len>
 * characters (when len is positive) or the first NUL character. Placing -1 in
 * <len> will make it virtually unbounded (~2GB long strings).
 */
int make_arg_list(const char *in, int len, uint64_t mask, struct arg **argp,
                  char **err_msg, const char **end_ptr, int *err_arg,
                  struct arg_list *al)
{
	int nbarg;
	int pos;
	struct arg *arg;
	const char *beg;
	const char *ptr_err = NULL;
	int min_arg;
	int empty;
	struct arg_list *new_al = al;

	*argp = NULL;

	empty = 0;
	if (!len || *in != '(') {
		/* it's already not for us, stop here */
		empty = 1;
		len = 0;
	} else {
		/* skip opening parenthesis */
		len--;
		in++;
	}

	min_arg = mask & ARGM_MASK;
	mask >>= ARGM_BITS;

	pos = 0;
	/* find between 0 and NBARGS the max number of args supported by the mask */
	for (nbarg = 0; nbarg < ARGM_NBARGS && ((mask >> (nbarg * ARGT_BITS)) & ARGT_MASK); nbarg++);

	if (!nbarg)
		goto end_parse;

	/* Note: an empty input string contains an empty argument if this argument
	 * is marked mandatory. Otherwise we can ignore it.
	 */
	if (empty && !min_arg)
		goto end_parse;

	arg = *argp = calloc(nbarg + 1, sizeof(**argp));

	if (!arg)
		goto alloc_err;

	/* Note: empty arguments after a comma always exist. */
	while (pos < nbarg) {
		unsigned int uint;
		int squote = 0, dquote = 0;
		char *out;

		chunk_reset(&trash);
		out = trash.area;

		while (len && *in && trash.data < trash.size - 1) {
			if (*in == '"' && !squote) {  /* double quote outside single quotes */
				if (dquote)
					dquote = 0;
				else
					dquote = 1;
				in++; len--;
				continue;
			}
			else if (*in == '\'' && !dquote) { /* single quote outside double quotes */
				if (squote)
					squote = 0;
				else
					squote = 1;
				in++; len--;
				continue;
			}
			else if (*in == '\\' && !squote && len != 1) {
				/* '\', ', ' ', '"' support being escaped by '\' */
				if (len == 1 || in[1] == 0)
					goto unquote_err;

				if (in[1] == '\\' || in[1] == ' ' || in[1] == '"' || in[1] == '\'') {
					in++; len--;
					*out++ = *in;
				}
				else if (in[1] == 'r') {
					in++; len--;
					*out++ = '\r';
				}
				else if (in[1] == 'n') {
					in++; len--;
					*out++ = '\n';
				}
				else if (in[1] == 't') {
					in++; len--;
					*out++ = '\t';
				}
				else {
					/* just a lone '\' */
					*out++ = *in;
				}
				in++; len--;
			}
			else {
				if (!squote && !dquote && (*in == ',' || *in == ')')) {
					/* end of argument */
					break;
				}
				/* verbatim copy */
				*out++ = *in++;
				len--;
			}
			trash.data = out - trash.area;
		}

		if (len && *in && *in != ',' && *in != ')')
			goto buffer_err;

		trash.area[trash.data] = 0;

		arg->type = (mask >> (pos * ARGT_BITS)) & ARGT_MASK;

		switch (arg->type) {
		case ARGT_SINT:
			if (!trash.data)	  // empty number
				goto empty_err;
			beg = trash.area;
			arg->data.sint = read_int64(&beg, trash.area + trash.data);
			if (beg < trash.area + trash.data)
				goto parse_err;
			arg->type = ARGT_SINT;
			break;

		case ARGT_FE:
		case ARGT_BE:
		case ARGT_TAB:
		case ARGT_SRV:
		case ARGT_USR:
		case ARGT_REG:
			/* These argument types need to be stored as strings during
			 * parsing then resolved later.
			 */
			arg->unresolved = 1;
			new_al = arg_list_add(al, arg, pos);

			/* fall through */
		case ARGT_STR:
			/* all types that must be resolved are stored as strings
			 * during the parsing. The caller must at one point resolve
			 * them and free the string.
			 */
			arg->data.str.area = my_strndup(trash.area, trash.data);
			arg->data.str.data = trash.data;
			arg->data.str.size = trash.data + 1;
			break;

		case ARGT_IPV4:
			if (!trash.data)    // empty address
				goto empty_err;

			if (inet_pton(AF_INET, trash.area, &arg->data.ipv4) <= 0)
				goto parse_err;
			break;

		case ARGT_MSK4:
			if (!trash.data)    // empty mask
				goto empty_err;

			if (!str2mask(trash.area, &arg->data.ipv4))
				goto parse_err;

			arg->type = ARGT_IPV4;
			break;

		case ARGT_IPV6:
			if (!trash.data)    // empty address
				goto empty_err;

			if (inet_pton(AF_INET6, trash.area, &arg->data.ipv6) <= 0)
				goto parse_err;
			break;

		case ARGT_MSK6:
			if (!trash.data)    // empty mask
				goto empty_err;

			if (!str2mask6(trash.area, &arg->data.ipv6))
				goto parse_err;

			arg->type = ARGT_IPV6;
			break;

		case ARGT_TIME:
			if (!trash.data)    // empty time
				goto empty_err;

			ptr_err = parse_time_err(trash.area, &uint, TIME_UNIT_MS);
			if (ptr_err) {
				if (ptr_err == PARSE_TIME_OVER || ptr_err == PARSE_TIME_UNDER)
					ptr_err = trash.area;
				goto parse_err;
			}
			arg->data.sint = uint;
			arg->type = ARGT_SINT;
			break;

		case ARGT_SIZE:
			if (!trash.data)    // empty size
				goto empty_err;

			ptr_err = parse_size_err(trash.area, &uint);
			if (ptr_err)
				goto parse_err;

			arg->data.sint = uint;
			arg->type = ARGT_SINT;
			break;

		case ARGT_PBUF_FNUM:
			if (!trash.data)
				goto empty_err;

			if (!parse_dotted_uints(trash.area, &arg->data.fid.ids, &arg->data.fid.sz))
				goto parse_err;

			break;

			/* FIXME: other types need to be implemented here */
		default:
			goto not_impl;
		}

		pos++;
		arg++;

		/* don't go back to parsing if we reached end */
		if (!len || !*in || *in == ')' || pos >= nbarg)
			break;

		/* skip comma */
		in++; len--;
	}

 end_parse:
	if (pos < min_arg) {
		/* not enough arguments */
		memprintf(err_msg,
		          "missing arguments (got %d/%d), type '%s' expected",
		          pos, min_arg, arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK]);
		goto err;
	}

	if (empty) {
		/* nothing to do */
	} else if (*in == ')') {
		/* skip the expected closing parenthesis */
		in++;
	} else {
		/* the caller is responsible for freeing this message */
		char *word = (len > 0) ? my_strndup(in, len) : (char *)in;

		if (*word)
			memprintf(err_msg, "expected ')' before '%s'", word);
		else
			memprintf(err_msg, "expected ')'");

		if (len > 0)
			free(word);
		/* when we're missing a right paren, the empty part preceding
		 * already created an empty arg, adding one to the position, so
		 * let's fix the reporting to avoid being confusing.
		 */
		if (pos > 1)
			pos--;
		goto err;
	}

	/* note that pos might be < nbarg and this is not an error, it's up to the
	 * caller to decide what to do with optional args.
	 */
	if (err_arg)
		*err_arg = pos;
	if (end_ptr)
		*end_ptr = in;
	return pos;

 err:
	if (new_al == al) {
		/* only free the arg area if we have not queued unresolved args
		 * still pointing to it.
		 */
		free_args(*argp);
		free(*argp);
	}
	*argp = NULL;
	if (err_arg)
		*err_arg = pos;
	if (end_ptr)
		*end_ptr = in;
	return -1;

 empty_err:
	/* If we've only got an empty set of parenthesis with nothing
	 * in between, there is no arg at all.
	 */
	if (!pos) {
		ha_free(argp);
	}

	if (pos >= min_arg)
		goto end_parse;

	memprintf(err_msg, "expected type '%s' at position %d, but got nothing",
	          arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK], pos + 1);
	goto err;

 parse_err:
	/* come here with the word attempted to parse in trash */
	memprintf(err_msg, "failed to parse '%s' as type '%s' at position %d",
	          trash.area, arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK], pos + 1);
	goto err;

 not_impl:
	memprintf(err_msg, "parsing for type '%s' was not implemented, please report this bug",
	          arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK]);
	goto err;

 buffer_err:
	memprintf(err_msg, "too small buffer size to store decoded argument %d, increase bufsize ?",
	          pos + 1);
	goto err;

 unquote_err:
	/* come here with the parsed part in <trash.area>:<trash.data> and the
	 * unparsable part in <in>.
	 */
	trash.area[trash.data] = 0;
	memprintf(err_msg, "failed to parse '%s' after '%s' as type '%s' at position %d",
	          in, trash.area, arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK], pos + 1);
	goto err;

alloc_err:
	memprintf(err_msg, "out of memory");
	goto err;
}

/* Free all args of an args array, taking care of unresolved arguments as well.
 * It stops at the ARGT_STOP, which must be present. The array itself is not
 * freed, it's up to the caller to do it. However it is returned, allowing to
 * call free(free_args(argptr)). It is valid to call it with a NULL args, and
 * nothing will be done).
 */
struct arg *free_args(struct arg *args)
{
	struct arg *arg;

	for (arg = args; arg && arg->type != ARGT_STOP; arg++) {
		if (arg->type == ARGT_STR || arg->unresolved)
			chunk_destroy(&arg->data.str);
		else if (arg->type == ARGT_REG)
			regex_free(arg->data.reg);
		else if (arg->type == ARGT_PBUF_FNUM)
			ha_free(&arg->data.fid.ids);
	}
	return args;
}
