/*
 * 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/tools.h>
#include <haproxy/chunk.h>
#include <types/global.h>
#include <haproxy/arg.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_ADDQ(&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(*arg));

	/* 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;
		memprintf(err_msg, "expected ')' before '%s'", word);
		if (len > 0)
			free(word);
		/* when we're missing a right paren, the empty part preceeding
		 * 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(*argp);
	}
	*argp = NULL;
	if (err_arg)
		*err_arg = pos;
	if (end_ptr)
		*end_ptr = in;
	return -1;

 empty_err:
	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;

}
