/***
 * Copyright 2020 HAProxy Technologies
 *
 * This file is part of the HAProxy OpenTracing filter.
 *
 * 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.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include "include.h"


#ifdef DEBUG_OT
struct flt_ot_debug               flt_ot_debug;
THREAD_LOCAL int                  dbg_indent_level = 0;
#endif

#ifdef OTC_DBG_MEM
static struct otc_dbg_mem_data    dbg_mem_data[1000000];
static struct otc_dbg_mem         dbg_mem;
#endif

static struct flt_ot_conf        *flt_ot_current_config = NULL;
static struct flt_ot_conf_tracer *flt_ot_current_tracer = NULL;
static struct flt_ot_conf_group  *flt_ot_current_group = NULL;
static struct flt_ot_conf_scope  *flt_ot_current_scope = NULL;
static struct flt_ot_conf_span   *flt_ot_current_span = NULL;


/***
 * NAME
 *   flt_ot_parse_strdup -
 *
 * ARGUMENTS
 *   ptr     -
 *   str     -
 *   err     -
 *   err_msg -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_strdup(char **ptr, const char *str, char **err, const char *err_msg)
{
	int retval = ERR_NONE;

	FLT_OT_FUNC("%p:%p, %p, %p:%p, \"%s\"", FLT_OT_DPTR_ARGS(ptr), str, FLT_OT_DPTR_ARGS(err), err_msg);

	*ptr = FLT_OT_STRDUP(str);
	if (*ptr == NULL) {
		FLT_OT_PARSE_ERR(err, "'%s' : out of memory", err_msg);

		retval |= ERR_ABORT | ERR_ALERT;
	}

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_keyword -
 *
 * ARGUMENTS
 *   ptr     -
 *   args    -
 *   cur_arg -
 *   pos     -
 *   err     -
 *   err_msg -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_keyword(char **ptr, char **args, int cur_arg, int pos, char **err, const char *err_msg)
{
	int retval = ERR_NONE;

	FLT_OT_FUNC("%p:%p, %p, %d, %d, %p:%p, \"%s\"", FLT_OT_DPTR_ARGS(ptr), args, cur_arg, pos, FLT_OT_DPTR_ARGS(err), err_msg);

	if (*ptr != NULL) {
		if (cur_arg == pos)
			FLT_OT_PARSE_ERR(err, FLT_OT_FMT_TYPE "%s already set", err_msg);
		else
			FLT_OT_PARSE_ERR(err, "'%s' : %s already set", args[cur_arg], err_msg);
	}
	else if (!FLT_OT_ARG_ISVALID(pos + 1)) {
		if (cur_arg == pos)
			FLT_OT_PARSE_ERR(err, FLT_OT_FMT_TYPE "no %s set", err_msg);
		else
			FLT_OT_PARSE_ERR(err, "'%s' : no %s set", args[cur_arg], err_msg);
	}
	else {
		retval = flt_ot_parse_strdup(ptr, args[pos + 1], err, args[cur_arg]);
	}

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_invalid_char -
 *
 * ARGUMENTS
 *   name -
 *   type -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   -
 */
static const char *flt_ot_parse_invalid_char(const char *name, int type)
{
	const char *retptr = NULL;

	FLT_OT_FUNC("\"%s\", %d", name, type);

	if (!FLT_OT_STR_ISVALID(name))
		FLT_OT_RETURN_EX(retptr, const char *, "%p");

	if (type == FLT_OT_PARSE_INVALID_CHAR) {
		retptr = invalid_char(name);
	}
	else if (type == FLT_OT_PARSE_INVALID_DOM) {
		retptr = invalid_domainchar(name);
	}
	else if (type == FLT_OT_PARSE_INVALID_CTX) {
		retptr = invalid_prefix_char(name);
	}
	else if (type == FLT_OT_PARSE_INVALID_VAR) {
		retptr = name;

		/*
		 * Allowed characters are letters, numbers and '_', the first
		 * character in the string must not be a number.
		 */
		if (!isdigit(*retptr))
			for (++retptr; (*retptr == '_') || isalnum(*retptr); retptr++);

		if (*retptr == '\0')
			retptr = NULL;
	}

	FLT_OT_RETURN_EX(retptr, const char *, "%p");
}


/***
 * NAME
 *   flt_ot_parse_cfg_check -
 *
 * ARGUMENTS
 *   file            -
 *   linenum         -
 *   args            -
 *   id              -
 *   parse_data      -
 *   parse_data_size -
 *   pdata           -
 *   err             -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_check(const char *file, int linenum, char **args, const void *id, const struct flt_ot_parse_data *parse_data, size_t parse_data_size, const struct flt_ot_parse_data **pdata, char **err)
{
	int i, argc, retval = ERR_NONE;

	FLT_OT_FUNC("\"%s\", %d, %p, %p, %p, %zu, %p:%p, %p:%p", file, linenum, args, id, parse_data, parse_data_size, FLT_OT_DPTR_ARGS(pdata), FLT_OT_DPTR_ARGS(err));

	FLT_OT_ARGS_DUMP();

	*pdata = NULL;

	/* First check here if args[0] is the correct keyword. */
	for (i = 0; (*pdata == NULL) && (i < parse_data_size); i++)
		if (strcmp(parse_data[i].name, args[0]) == 0)
			*pdata = parse_data + i;

	if (*pdata == NULL)
		FLT_OT_PARSE_ERR(err, "'%s' : unknown keyword", args[0]);
	else
		argc = flt_ot_args_count(args);

	if ((retval & ERR_CODE) || (id == NULL))
		/* Do nothing. */;
	else if ((id != flt_ot_current_tracer) && (flt_ot_current_config->tracer == NULL))
		FLT_OT_PARSE_ERR(err, "tracer not defined");

	/*
	 * Checking that fewer arguments are specified in the configuration
	 * line than is required.
	 */
	if (!(retval & ERR_CODE))
		if (argc < (*pdata)->args_min)
			FLT_OT_PARSE_ERR(err, "'%s' : too few arguments (use '%s%s')", args[0], (*pdata)->name, (*pdata)->usage);

	/*
	 * Checking that more arguments are specified in the configuration
	 * line than the maximum allowed.
	 */
	if (!(retval & ERR_CODE) && ((*pdata)->args_max > 0))
		if (argc > (*pdata)->args_max)
			FLT_OT_PARSE_ERR(err, "'%s' : too many arguments (use '%s%s')", args[0], (*pdata)->name, (*pdata)->usage);

	/* Checking that the first argument has only allowed characters. */
	if (!(retval & ERR_CODE) && ((*pdata)->check_name != FLT_OT_PARSE_INVALID_NONE)) {
		const char *ic;

		ic = flt_ot_parse_invalid_char(args[1], (*pdata)->check_name);
		if (ic != NULL)
			FLT_OT_PARSE_ERR(err, "%s '%s' : invalid character '%c'", args[0], args[1], *ic);
	}

	/* Checking that the data group name is defined. */
	if (!(retval & ERR_CODE) && (*pdata)->flag_check_id && (id == NULL))
		FLT_OT_PARSE_ERR(err, "'%s' : %s ID not set (use '%s%s')", args[0], parse_data[1].name, parse_data[1].name, parse_data[1].usage);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_cfg_sample_expr -
 *
 * ARGUMENTS
 *   file    -
 *   linenum -
 *   args    -
 *   idx     -
 *   head    -
 *   err     -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_sample_expr(const char *file, int linenum, char **args, int *idx, struct list *head, char **err)
{
	struct flt_ot_conf_sample_expr *expr;
	int                             retval = ERR_NONE;

	FLT_OT_FUNC("\"%s\", %d, %p, %p, %p, %p:%p", file, linenum, args, idx, head, FLT_OT_DPTR_ARGS(err));

	expr = flt_ot_conf_sample_expr_init(args[*idx], linenum, head, err);
	if (expr != NULL) {
		expr->expr = sample_parse_expr(args, idx, file, linenum, err, &(flt_ot_current_config->proxy->conf.args), NULL);
		if (expr->expr != NULL)
			FLT_OT_DBG(3, "sample expression '%s' added", expr->value);
		else
			retval |= ERR_ABORT | ERR_ALERT;
	} else {
			retval |= ERR_ABORT | ERR_ALERT;
	}

	if (retval & ERR_CODE)
		flt_ot_conf_sample_expr_free(&expr);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_cfg_sample -
 *
 * ARGUMENTS
 *   file    -
 *   linenum -
 *   args    -
 *   head    -
 *   err     -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_sample(const char *file, int linenum, char **args, struct list *head, char **err)
{
	struct flt_ot_conf_sample *sample;
	int                        idx = 2, retval = ERR_NONE;

	FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p", file, linenum, args, head, FLT_OT_DPTR_ARGS(err));

	sample = flt_ot_conf_sample_init(args, linenum, head, err);
	if (sample == NULL)
		FLT_OT_PARSE_ERR(err, "'%s' : out of memory", args[0]);

	if (!(retval & ERR_CODE)) {
		flt_ot_current_config->proxy->conf.args.ctx  = ARGC_OT;
		flt_ot_current_config->proxy->conf.args.file = file;
		flt_ot_current_config->proxy->conf.args.line = linenum;

		while (!(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(idx))
			retval = flt_ot_parse_cfg_sample_expr(file, linenum, args, &idx, &(sample->exprs), err);

		flt_ot_current_config->proxy->conf.args.file = NULL;
		flt_ot_current_config->proxy->conf.args.line = 0;
	}

	if (retval & ERR_CODE)
		flt_ot_conf_sample_free(&sample);
	else
		FLT_OT_DBG(3, "sample '%s' -> '%s' added", sample->key, sample->value);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_cfg_str -
 *
 * ARGUMENTS
 *   file    -
 *   linenum -
 *   args    -
 *   head    -
 *   err     -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_str(const char *file, int linenum, char **args, struct list *head, char **err)
{
	struct flt_ot_conf_str *str = NULL;
	int                     i, retval = ERR_NONE;

	FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p", file, linenum, args, head, FLT_OT_DPTR_ARGS(err));

	for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++)
		if (flt_ot_conf_str_init(args[i], linenum, head, err) == NULL)
			retval |= ERR_ABORT | ERR_ALERT;

	if (retval & ERR_CODE)
		flt_ot_conf_str_free(&str);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_cfg_file -
 *
 * ARGUMENTS
 *   ptr     -
 *   file    -
 *   linenum -
 *   args    -
 *   err     -
 *   err_msg -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_file(char **ptr, const char *file, int linenum, char **args, char **err, const char *err_msg)
{
	int retval = ERR_NONE;

	FLT_OT_FUNC("%p:%p, \"%s\", %d, %p, %p:%p, \"%s\"", FLT_OT_DPTR_ARGS(ptr), file, linenum, args, FLT_OT_DPTR_ARGS(err), err_msg);

	if (!FLT_OT_ARG_ISVALID(1))
		FLT_OT_PARSE_ERR(err, "'%s' : no %s specified", flt_ot_current_tracer->id, err_msg);
	else if (alertif_too_many_args(1, file, linenum, args, &retval))
		retval |= ERR_ABORT | ERR_ALERT;
	else if (access(args[1], R_OK) == -1)
		FLT_OT_PARSE_ERR(err, "'%s' : %s", args[1], strerror(errno));
	else
		retval = flt_ot_parse_keyword(ptr, args, 0, 0, err, err_msg);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_check_scope -
 *
 * ARGUMENTS
 *   This function takes no arguments.
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns TRUE in case the configuration is not in the currently defined
 *   scope, FALSE otherwise.
 */
static bool flt_ot_parse_check_scope(void)
{
	bool retval = 0;

	if ((cfg_scope != NULL) && (flt_ot_current_config->id != NULL) && (strcmp(flt_ot_current_config->id, cfg_scope) != 0)) {
		FLT_OT_DBG(1, "cfg_scope: '%s', id: '%s'", cfg_scope, flt_ot_current_config->id);

		retval = 1;
	}

	return retval;
}


/***
 * NAME
 *   flt_ot_parse_cfg_tracer -
 *
 * ARGUMENTS
 *   file    -
 *   linenum -
 *   args    -
 *   kw_mod  -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_tracer(const char *file, int linenum, char **args, int kw_mod)
{
#define FLT_OT_PARSE_TRACER_DEF(a,b,c,d,e,f,g)   { FLT_OT_PARSE_TRACER_##a, b, FLT_OT_PARSE_INVALID_##c, d, e, f, g },
	static const struct flt_ot_parse_data  parse_data[] = { FLT_OT_PARSE_TRACER_DEFINES };
#undef FLT_OT_PARSE_TRACER_DEF
	const struct flt_ot_parse_data        *pdata = NULL;
	char                                  *err = NULL, *err_log = NULL;
	int                                    i, retval = ERR_NONE;

	FLT_OT_FUNC("\"%s\", %d, %p, 0x%08x", file, linenum, args, kw_mod);

	if (flt_ot_parse_check_scope())
		FLT_OT_RETURN_INT(retval);

	retval = flt_ot_parse_cfg_check(file, linenum, args, flt_ot_current_tracer, parse_data, FLT_OT_TABLESIZE(parse_data), &pdata, &err);
	if (retval & ERR_CODE) {
		FLT_OT_PARSE_IFERR_ALERT();

		FLT_OT_RETURN_INT(retval);
	}

	if (pdata->keyword == FLT_OT_PARSE_TRACER_ID) {
		if (flt_ot_current_config->tracer != NULL) {
			FLT_OT_PARSE_ERR(&err, "'%s' : tracer can be defined only once", args[1]);
		} else {
			flt_ot_current_tracer = flt_ot_conf_tracer_init(args[1], linenum, &err);
			if (flt_ot_current_tracer == NULL)
				retval |= ERR_ABORT | ERR_ALERT;
		}
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_LOG) {
		if (parse_logsrv(args, &(flt_ot_current_tracer->proxy_log.logsrvs), kw_mod == KWM_NO, file, linenum, &err_log) == 0) {
			FLT_OT_PARSE_ERR(&err, "'%s %s ...' : %s", args[0], args[1], err_log);
			FLT_OT_FREE_CLEAR(err_log);

			retval |= ERR_ABORT | ERR_ALERT;
		} else {
			flt_ot_current_tracer->logging |= FLT_OT_LOGGING_ON;
		}
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_CONFIG) {
		retval = flt_ot_parse_cfg_file(&(flt_ot_current_tracer->config), file, linenum, args, &err, "configuration file");
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_PLUGIN) {
		retval = flt_ot_parse_cfg_file(&(flt_ot_current_tracer->plugin), file, linenum, args, &err, "plugin library");
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_GROUPS) {
		for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++)
			if (flt_ot_conf_ph_init(args[i], linenum, &(flt_ot_current_tracer->ph_groups), &err) == NULL)
				retval |= ERR_ABORT | ERR_ALERT;
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_SCOPES) {
		for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++)
			if (flt_ot_conf_ph_init(args[i], linenum, &(flt_ot_current_tracer->ph_scopes), &err) == NULL)
				retval |= ERR_ABORT | ERR_ALERT;
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_ACL) {
		if (strcasecmp(args[1], "or") == 0)
			FLT_OT_PARSE_ERR(&err, "'%s %s ...' : invalid ACL name", args[0], args[1]);
		else if (parse_acl((const char **)args + 1, &(flt_ot_current_tracer->acls), &err, &(flt_ot_current_config->proxy->conf.args), file, linenum) == NULL)
			retval |= ERR_ABORT | ERR_ALERT;
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_RATE_LIMIT) {
		flt_ot_current_tracer->rate_limit = FLT_OT_FLOAT_U32(flt_ot_strtod(args[1], 0.0, FLT_OT_RATE_LIMIT_MAX, &err), FLT_OT_RATE_LIMIT_MAX);
	}
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_OPTION) {
		if (strcmp(args[1], FLT_OT_PARSE_OPTION_DISABLED) == 0) {
			flt_ot_current_tracer->flag_disabled = (kw_mod == KWM_NO) ? 0 : 1;
		}
		else if (strcmp(args[1], FLT_OT_PARSE_OPTION_HARDERR) == 0) {
			flt_ot_current_tracer->flag_harderr = (kw_mod == KWM_NO) ? 0 : 1;
		}
		else if (strcmp(args[1], FLT_OT_PARSE_OPTION_NOLOGNORM) == 0) {
			if (kw_mod == KWM_NO)
				flt_ot_current_tracer->logging &= ~FLT_OT_LOGGING_NOLOGNORM;
			else
				flt_ot_current_tracer->logging |= FLT_OT_LOGGING_NOLOGNORM;
		}
		else
			FLT_OT_PARSE_ERR(&err, "'%s' : unknown option '%s'", args[0], args[1]);
	}
#ifdef DEBUG_OT
	else if (pdata->keyword == FLT_OT_PARSE_TRACER_DEBUG_LEVEL) {
		flt_ot_debug.level = flt_ot_strtoll(args[1], 0, 255, &err);
	}
#else
	else {
		FLT_OT_PARSE_WARNING("'%s' : keyword ignored", file, linenum, args[0]);
	}
#endif

	FLT_OT_PARSE_IFERR_ALERT();

	if ((retval & ERR_CODE) && (flt_ot_current_tracer != NULL))
		flt_ot_conf_tracer_free(&flt_ot_current_tracer);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_post_parse_cfg_tracer -
 *
 * ARGUMENTS
 *   This function takes no arguments.
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_post_parse_cfg_tracer(void)
{
	char errbuf[BUFSIZ] = "";
	int  retval = ERR_NONE;

	FLT_OT_FUNC("");

	if (flt_ot_current_tracer == NULL)
		FLT_OT_RETURN_INT(retval);

	flt_ot_current_config->tracer = flt_ot_current_tracer;

	if (flt_ot_current_tracer->id == NULL)
		FLT_OT_RETURN_INT(retval);

	if (flt_ot_current_tracer->config == NULL) {
		FLT_OT_POST_PARSE_ALERT("tracer '%s' has no configuration file specified", flt_ot_current_tracer->cfg_line, flt_ot_current_tracer->id);
	} else {
		flt_ot_current_tracer->cfgbuf = otc_file_read(flt_ot_current_tracer->config, "#", errbuf, sizeof(errbuf));
		if (flt_ot_current_tracer->cfgbuf == NULL)
			FLT_OT_POST_PARSE_ALERT("tracer '%s' %s", flt_ot_current_tracer->cfg_line, flt_ot_current_tracer->id, (*errbuf == '\0') ? "cannot load configuration file" : errbuf);
	}

	if (flt_ot_current_tracer->plugin == NULL)
		FLT_OT_POST_PARSE_ALERT("tracer '%s' has no plugin library specified", flt_ot_current_tracer->cfg_line, flt_ot_current_tracer->id);

	flt_ot_current_tracer = NULL;

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_cfg_group -
 *
 * ARGUMENTS
 *   file    -
 *   linenum -
 *   args    -
 *   kw_mod  -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_group(const char *file, int linenum, char **args, int kw_mod)
{
#define FLT_OT_PARSE_GROUP_DEF(a,b,c,d,e,f,g)   { FLT_OT_PARSE_GROUP_##a, b, FLT_OT_PARSE_INVALID_##c, d, e, f, g },
	static const struct flt_ot_parse_data  parse_data[] = { FLT_OT_PARSE_GROUP_DEFINES };
#undef FLT_OT_PARSE_GROUP_DEF
	const struct flt_ot_parse_data        *pdata = NULL;
	char                                  *err = NULL;
	int                                    i, retval = ERR_NONE;

	FLT_OT_FUNC("\"%s\", %d, %p, 0x%08x", file, linenum, args, kw_mod);

	if (flt_ot_parse_check_scope())
		FLT_OT_RETURN_INT(retval);

	retval = flt_ot_parse_cfg_check(file, linenum, args, flt_ot_current_group, parse_data, FLT_OT_TABLESIZE(parse_data), &pdata, &err);
	if (retval & ERR_CODE) {
		FLT_OT_PARSE_IFERR_ALERT();

		FLT_OT_RETURN_INT(retval);
	}

	if (pdata->keyword == FLT_OT_PARSE_GROUP_ID) {
		flt_ot_current_group = flt_ot_conf_group_init(args[1], linenum, &(flt_ot_current_config->groups), &err);
		if (flt_ot_current_config == NULL)
			retval |= ERR_ABORT | ERR_ALERT;
	}
	else if (pdata->keyword == FLT_OT_PARSE_GROUP_SCOPES) {
		for (i = 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(i); i++)
			if (flt_ot_conf_ph_init(args[i], linenum, &(flt_ot_current_group->ph_scopes), &err) == NULL)
				retval |= ERR_ABORT | ERR_ALERT;
	}

	FLT_OT_PARSE_IFERR_ALERT();

	if ((retval & ERR_CODE) && (flt_ot_current_group != NULL))
		flt_ot_conf_group_free(&flt_ot_current_group);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_post_parse_cfg_group -
 *
 * ARGUMENTS
 *   This function takes no arguments.
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_post_parse_cfg_group(void)
{
	int retval = ERR_NONE;

	FLT_OT_FUNC("");

	if (flt_ot_current_group == NULL)
		FLT_OT_RETURN_INT(retval);

	/* Check that the group has at least one scope defined. */
	if (LIST_ISEMPTY(&(flt_ot_current_group->ph_scopes)))
		FLT_OT_POST_PARSE_ALERT("group '%s' has no defined scope(s)", flt_ot_current_group->cfg_line, flt_ot_current_group->id);

	flt_ot_current_group = NULL;

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_cfg_scope_ctx -
 *
 * ARGUMENTS
 *   args    -
 *   cur_arg -
 *   err     -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_scope_ctx(char **args, int cur_arg, char **err)
{
	uint8_t flags = 0;
	int     retval = ERR_NONE;

	FLT_OT_FUNC("%p, %d, %p:%p", args, cur_arg, FLT_OT_DPTR_ARGS(err));

	if (strcmp(args[cur_arg], FLT_OT_PARSE_CTX_USE_HEADERS) == 0)
		flags = FLT_OT_CTX_USE_HEADERS;
#ifdef USE_OT_VARS
	else if (strcmp(args[cur_arg], FLT_OT_PARSE_CTX_USE_VARS) == 0)
		flags = FLT_OT_CTX_USE_VARS;
#endif
	else
		FLT_OT_PARSE_ERR(err, "'%s' : invalid context storage type", args[0]);

	if (flags == 0)
		/* Do nothing. */;
	else if (flt_ot_current_span->ctx_flags & flags)
		FLT_OT_PARSE_ERR(err, "'%s' : %s already used", args[0], args[cur_arg]);
	else
		flt_ot_current_span->ctx_flags |= flags;

	FLT_OT_DBG(2, "ctx_flags: 0x%02hhx (0x%02hhx)", flt_ot_current_span->ctx_flags, flags);

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_acl -
 *
 * ARGUMENTS
 *   file    -
 *   linenum -
 *   px      -
 *   args    -
 *   err     -
 *   head    -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   -
 */
static struct acl_cond *flt_ot_parse_acl(const char *file, int linenum, struct proxy *px, const char **args, char **err, struct list *head, ...)
{
	va_list          ap;
	int              n = 0;
	struct acl_cond *retptr = NULL;

	FLT_OT_FUNC("\"%s\", %d, %p, %p, %p:%p, %p, ...", file, linenum, px, args, FLT_OT_DPTR_ARGS(err), head);

	for (va_start(ap, head); (retptr == NULL) && (head != NULL); head = va_arg(ap, typeof(head)), n++) {
		retptr = build_acl_cond(file, linenum, head, px, args, (n == 0) ? err : NULL);
		if (retptr != NULL)
			FLT_OT_DBG(2, "ACL build done, using list %p %d", head, n);
	}
	va_end(ap);

	if ((retptr != NULL) && (err != NULL))
		FLT_OT_FREE_CLEAR(*err);

	FLT_OT_RETURN_PTR(retptr);
}


/***
 * NAME
 *   flt_ot_parse_cfg_scope -
 *
 * ARGUMENTS
 *   file    -
 *   linenum -
 *   args    -
 *   kw_mod  -
 *
 * DESCRIPTION
 *   Function used to load the scope block configuration.
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg_scope(const char *file, int linenum, char **args, int kw_mod)
{
#define FLT_OT_PARSE_SCOPE_DEF(a,b,c,d,e,f,g)   { FLT_OT_PARSE_SCOPE_##a, b, FLT_OT_PARSE_INVALID_##c, d, e, f, g },
	static const struct flt_ot_parse_data  parse_data[] = { FLT_OT_PARSE_SCOPE_DEFINES };
#undef FLT_OT_PARSE_SCOPE_DEF
	const struct flt_ot_parse_data        *pdata = NULL;
	char                                  *err = NULL;
	int                                    i, retval = ERR_NONE;

	FLT_OT_FUNC("\"%s\", %d, %p, 0x%08x", file, linenum, args, kw_mod);

	if (flt_ot_parse_check_scope())
		FLT_OT_RETURN_INT(retval);

	retval = flt_ot_parse_cfg_check(file, linenum, args, flt_ot_current_span, parse_data, FLT_OT_TABLESIZE(parse_data), &pdata, &err);
	if (retval & ERR_CODE) {
		FLT_OT_PARSE_IFERR_ALERT();

		FLT_OT_RETURN_INT(retval);
	}

	if (pdata->keyword == FLT_OT_PARSE_SCOPE_ID) {
		/* Initialization of a new scope. */
		flt_ot_current_scope = flt_ot_conf_scope_init(args[1], linenum, &(flt_ot_current_config->scopes), &err);
		if (flt_ot_current_scope == NULL)
			retval |= ERR_ABORT | ERR_ALERT;
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_SPAN) {
		/*
		 * Checking if this is the beginning of the definition of
		 * a new span.
		 */
		if (flt_ot_current_span != NULL) {
			FLT_OT_DBG(3, "span '%s' (done)", flt_ot_current_span->id);

			flt_ot_current_span = NULL;
		}

		/* Initialization of a new span. */
		flt_ot_current_span = flt_ot_conf_span_init(args[1], linenum, &(flt_ot_current_scope->spans), &err);

		/*
		 * In case the span has a defined reference,
		 * the correctness of the arguments is checked here.
		 */
		if (flt_ot_current_span == NULL) {
			retval |= ERR_ABORT | ERR_ALERT;
		}
		else if (FLT_OT_ARG_ISVALID(2)) {
			for (i = 2; (i < pdata->args_max) && FLT_OT_ARG_ISVALID(i); i++)
				if (strcmp(args[i], FLT_OT_PARSE_SPAN_ROOT) == 0) {
					if (flt_ot_current_span->flag_root)
						FLT_OT_PARSE_ERR(&err, "'%s' : already set (use '%s%s')", args[i], pdata->name, pdata->usage);
					else
						flt_ot_current_span->flag_root = 1;
				}
				else if ((strcmp(args[i], FLT_OT_PARSE_SPAN_REF_CHILD) == 0) || (strcmp(args[i], FLT_OT_PARSE_SPAN_REF_FOLLOWS) == 0)) {
					if (!FLT_OT_ARG_ISVALID(i + 1)) {
						FLT_OT_PARSE_ERR(&err, "'%s' : too few arguments (use '%s%s')", args[i], pdata->name, pdata->usage);
					}
					else if (strcmp(args[i++], FLT_OT_PARSE_SPAN_REF_CHILD) == 0) {
						flt_ot_current_span->ref_type   = otc_span_reference_child_of;
						flt_ot_current_span->ref_id_len = strlen(args[i]);

						retval = flt_ot_parse_strdup(&(flt_ot_current_span->ref_id), args[i], &err, args[1]);
					}
					else {
						flt_ot_current_span->ref_type   = otc_span_reference_follows_from;
						flt_ot_current_span->ref_id_len = strlen(args[i]);

						retval = flt_ot_parse_strdup(&(flt_ot_current_span->ref_id), args[i], &err, args[1]);
					}
				}
				else {
					FLT_OT_PARSE_ERR(&err, "'%s' : invalid argument (use '%s%s')", args[i], pdata->name, pdata->usage);
				}
		}
		else {
			/*
			 * This is not a faulty configuration, only such a case
			 * will be logged.
			 */
			FLT_OT_DBG(3, "new span '%s' without reference", flt_ot_current_span->id);
		}
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_TAG) {
		retval = flt_ot_parse_cfg_sample(file, linenum, args, &(flt_ot_current_span->tags), &err);
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_LOG) {
		retval = flt_ot_parse_cfg_sample(file, linenum, args, &(flt_ot_current_span->logs), &err);
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_BAGGAGE) {
		retval = flt_ot_parse_cfg_sample(file, linenum, args, &(flt_ot_current_span->baggages), &err);
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_INJECT) {
		/*
		 * Automatic context name generation can be specified here
		 * if the contents of the FLT_OT_PARSE_CTX_AUTONAME macro
		 * are used as the name.  In that case, if the context is
		 * after a particular event, it gets its name; otherwise
		 * it gets the name of the current span.
		 */
		if (flt_ot_current_span->ctx_id != NULL)
			FLT_OT_PARSE_ERR(&err, "'%s' : only one context per span is allowed", args[1]);
		else if (strcmp(args[1], FLT_OT_PARSE_CTX_AUTONAME) != 0)
			retval = flt_ot_parse_strdup(&(flt_ot_current_span->ctx_id), args[1], &err, args[0]);
		else if (flt_ot_current_scope->event != FLT_OT_EVENT_REQ_NONE)
			retval = flt_ot_parse_strdup(&(flt_ot_current_span->ctx_id), flt_ot_event_data[flt_ot_current_scope->event].name, &err, args[0]);
		else
			retval = flt_ot_parse_strdup(&(flt_ot_current_span->ctx_id), flt_ot_current_span->id, &err, args[0]);

		if (flt_ot_current_span->ctx_id != NULL) {
			flt_ot_current_span->ctx_id_len = strlen(flt_ot_current_span->ctx_id);

			/*
			 * Here is checked the context storage type; which, if
			 * not explicitly specified, is set to HTTP headers.
			 *
			 * It is possible to use both types of context storage
			 * at the same time.
			 */
			if (FLT_OT_ARG_ISVALID(2)) {
				retval = flt_ot_parse_cfg_scope_ctx(args, 2, &err);
				if (!(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(3))
					retval = flt_ot_parse_cfg_scope_ctx(args, 3, &err);
			} else {
				flt_ot_current_span->ctx_flags = FLT_OT_CTX_USE_HEADERS;
			}
		}
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_EXTRACT) {
		struct flt_ot_conf_context *conf_ctx;

		/*
		 * Here is checked the context storage type; which, if
		 * not explicitly specified, is set to HTTP headers.
		 */
		conf_ctx = flt_ot_conf_context_init(args[1], linenum, &(flt_ot_current_scope->contexts), &err);
		if (conf_ctx == NULL)
			retval |= ERR_ABORT | ERR_ALERT;
		else if (!FLT_OT_ARG_ISVALID(2))
			conf_ctx->flags = FLT_OT_CTX_USE_HEADERS;
		else if (strcmp(args[2], FLT_OT_PARSE_CTX_USE_HEADERS) == 0)
			conf_ctx->flags = FLT_OT_CTX_USE_HEADERS;
#ifdef USE_OT_VARS
		else if (strcmp(args[2], FLT_OT_PARSE_CTX_USE_VARS) == 0)
			conf_ctx->flags = FLT_OT_CTX_USE_VARS;
#endif
		else
			FLT_OT_PARSE_ERR(&err, "'%s' : invalid context storage type", args[2]);
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_FINISH) {
		retval = flt_ot_parse_cfg_str(file, linenum, args, &(flt_ot_current_scope->finish), &err);
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_ACL) {
		if (strcasecmp(args[1], "or") == 0)
			FLT_OT_PARSE_ERR(&err, "'%s %s ...' : invalid ACL name", args[0], args[1]);
		else if (parse_acl((const char **)args + 1, &(flt_ot_current_scope->acls), &err, &(flt_ot_current_config->proxy->conf.args), file, linenum) == NULL)
			retval |= ERR_ABORT | ERR_ALERT;
	}
	else if (pdata->keyword == FLT_OT_PARSE_SCOPE_EVENT) {
		/* Scope can only have one event defined. */
		if (flt_ot_current_scope->event != FLT_OT_EVENT_REQ_NONE) {
			FLT_OT_PARSE_ERR(&err, "'%s' : event already set", flt_ot_current_scope->id);
		} else {
			/* Check the event name. */
			for (i = 0; i < FLT_OT_TABLESIZE(flt_ot_event_data); i++)
				if (strcmp(flt_ot_event_data[i].name, args[1]) == 0) {
					flt_ot_current_scope->event = i;

					break;
				}

			/*
			 * The event can have some condition defined and this
			 * is checked here.
			 */
			if (flt_ot_current_scope->event == FLT_OT_EVENT_REQ_NONE) {
				FLT_OT_PARSE_ERR(&err, "'%s' : unknown event", args[1]);
			}
			else if (!FLT_OT_ARG_ISVALID(2)) {
				/* Do nothing. */
			}
			else if ((strcmp(args[2], FLT_OT_CONDITION_IF) == 0) || (strcmp(args[2], FLT_OT_CONDITION_UNLESS) == 0)) {
				/*
				 * We will first try to build ACL condition using
				 * local settings and then if that fails, using
				 * global settings (from tracer block).  If it
				 * also fails, then try to use ACL defined in
				 * the HAProxy configuration.
				 */
				flt_ot_current_scope->cond = flt_ot_parse_acl(file, linenum, flt_ot_current_config->proxy, (const char **)args + 2, &err, &(flt_ot_current_scope->acls), &(flt_ot_current_config->tracer->acls), &(flt_ot_current_config->proxy->acl), NULL);
				if (flt_ot_current_scope->cond == NULL)
					retval |= ERR_ABORT | ERR_ALERT;
			}
			else {
				FLT_OT_PARSE_ERR(&err, "'%s' : expects either 'if' or 'unless' followed by a condition but found '%s'", args[1], args[2]);
			}

			if (!(retval & ERR_CODE))
				FLT_OT_DBG(3, "event '%s'", args[1]);
		}
	}

	FLT_OT_PARSE_IFERR_ALERT();

	if ((retval & ERR_CODE) && (flt_ot_current_scope != NULL)) {
		flt_ot_conf_scope_free(&flt_ot_current_scope);

		flt_ot_current_span = NULL;
	}

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_post_parse_cfg_scope -
 *
 * ARGUMENTS
 *   This function takes no arguments.
 *
 * DESCRIPTION
 *   In this function the correctness of the complete scope block is examined.
 *   This does not mean that all elements are checked here, but only those for
 *   which it has not been possible to establish their complete correctness in
 *   the function flt_ot_parse_cfg_scope().
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_post_parse_cfg_scope(void)
{
	struct flt_ot_conf_span *conf_span;
	int                      retval = ERR_NONE;

	FLT_OT_FUNC("");

	if (flt_ot_current_scope == NULL)
		FLT_OT_RETURN_INT(retval);

	/* If span context inject is used, check that this is possible. */
	list_for_each_entry(conf_span, &(flt_ot_current_scope->spans), list)
		if ((conf_span->ctx_id != NULL) && (conf_span->ctx_flags & FLT_OT_CTX_USE_HEADERS))
			if (!flt_ot_event_data[flt_ot_current_scope->event].flag_http_inject)
				FLT_OT_POST_PARSE_ALERT("inject '%s' : cannot use on this event", conf_span->cfg_line, conf_span->ctx_id);

	if (retval & ERR_CODE)
		flt_ot_conf_scope_free(&flt_ot_current_scope);

	flt_ot_current_scope = NULL;
	flt_ot_current_span  = NULL;

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse_cfg -
 *
 * ARGUMENTS
 *   conf     -
 *   flt_name -
 *   err      -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse_cfg(struct flt_ot_conf *conf, const char *flt_name, char **err)
{
	struct list backup_sections;
	int         retval = ERR_ABORT | ERR_ALERT;

	FLT_OT_FUNC("%p, \"%s\", %p:%p", conf, flt_name, FLT_OT_DPTR_ARGS(err));

	flt_ot_current_config = conf;

	/* Backup sections. */
	LIST_INIT(&backup_sections);
	cfg_backup_sections(&backup_sections);

	/* Register new OT sections and parse the OT filter configuration file. */
	if (!cfg_register_section(FLT_OT_PARSE_SECTION_TRACER_ID, flt_ot_parse_cfg_tracer, flt_ot_post_parse_cfg_tracer))
		/* Do nothing. */;
	else if (!cfg_register_section(FLT_OT_PARSE_SECTION_GROUP_ID, flt_ot_parse_cfg_group, flt_ot_post_parse_cfg_group))
		/* Do nothing. */;
	else if (!cfg_register_section(FLT_OT_PARSE_SECTION_SCOPE_ID, flt_ot_parse_cfg_scope, flt_ot_post_parse_cfg_scope))
		/* Do nothing. */;
	else if (access(conf->cfg_file, R_OK) == -1)
		FLT_OT_PARSE_ERR(err, "'%s' : %s", conf->cfg_file, strerror(errno));
	else
		retval = readcfgfile(conf->cfg_file);

	/* Unregister OT sections and restore previous sections. */
	cfg_unregister_sections();
	cfg_restore_sections(&backup_sections);

	flt_ot_current_config = NULL;

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_parse -
 *
 * ARGUMENTS
 *   args    -
 *   cur_arg -
 *   px      -
 *   fconf   -
 *   err     -
 *   private -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   Returns ERR_NONE (== 0) in case of success,
 *   or a combination of ERR_* flags if an error is encountered.
 */
static int flt_ot_parse(char **args, int *cur_arg, struct proxy *px, struct flt_conf *fconf, char **err, void *private)
{
	struct flt_ot_conf *conf = NULL;
	int                 pos, retval = ERR_NONE;

#ifdef DEBUG_OT
	FLT_OT_RUN_ONCE(
#  ifndef DEBUG_OT_SYSTIME
		(void)memcpy(&(flt_ot_debug.start), &now, sizeof(flt_ot_debug.start));
#  endif

		flt_ot_debug.level = FLT_OT_DEBUG_LEVEL;
	);
#endif

	FLT_OT_FUNC("%p, %p, %p, %p, %p:%p, %p", args, cur_arg, px, fconf, FLT_OT_DPTR_ARGS(err), private);

#ifdef OTC_DBG_MEM
	FLT_OT_RUN_ONCE(
		if (otc_dbg_mem_init(&dbg_mem, dbg_mem_data, FLT_OT_TABLESIZE(dbg_mem_data), 0xff) == -1) {
			FLT_OT_PARSE_ERR(err, "cannot initialize memory debugger");

			FLT_OT_RETURN_INT(retval);
		}
	);
#endif

	FLT_OT_ARGS_DUMP();

	conf = flt_ot_conf_init(px);
	if (conf == NULL) {
		FLT_OT_PARSE_ERR(err, "'%s' : out of memory", args[*cur_arg]);

		FLT_OT_RETURN_INT(retval);
	}

	for (pos = *cur_arg + 1; !(retval & ERR_CODE) && FLT_OT_ARG_ISVALID(pos); pos++) {
		FLT_OT_DBG(3, "args[%d:2] : { '%s' '%s' }", pos, args[pos], args[pos + 1]);

		if (strcmp(args[pos], FLT_OT_OPT_FILTER_ID) == 0) {
			retval = flt_ot_parse_keyword(&(conf->id), args, *cur_arg, pos, err, "name");
			pos++;
		}
		else if (strcmp(args[pos], FLT_OT_OPT_CONFIG) == 0) {
			retval = flt_ot_parse_keyword(&(conf->cfg_file), args, *cur_arg, pos, err, "configuration file");
			if (!(retval & ERR_CODE))
				retval = flt_ot_parse_cfg(conf, args[*cur_arg], err);
			pos++;
		}
		else {
			FLT_OT_PARSE_ERR(err, "'%s' : unknown keyword '%s'", args[*cur_arg], args[pos]);
		}
	}

	/* If the OpenTracing filter ID is not set, use default name. */
	if (!(retval & ERR_CODE) && (conf->id == NULL)) {
		ha_warning("parsing : " FLT_OT_FMT_TYPE FLT_OT_FMT_NAME "'no filter id set, using default id '%s'\n", FLT_OT_OPT_FILTER_ID_DEFAULT);

		retval = flt_ot_parse_strdup(&(conf->id), FLT_OT_OPT_FILTER_ID_DEFAULT, err, args[*cur_arg]);
	}

	if (!(retval & ERR_CODE) && (conf->cfg_file == NULL))
		FLT_OT_PARSE_ERR(err, "'%s' : no configuration file specified", args[*cur_arg]);

	if (retval & ERR_CODE) {
		flt_ot_conf_free(&conf);
	} else {
		fconf->id   = ot_flt_id;
		fconf->ops  = &flt_ot_ops;
		fconf->conf = conf;

		*cur_arg = pos;

		FLT_OT_DBG(3, "filter set: id '%s', config '%s'", conf->id, conf->cfg_file);
	}

	FLT_OT_RETURN_INT(retval);
}


/* Declare the filter parser for FLT_OT_OPT_NAME keyword. */
static struct flt_kw_list flt_kws = { FLT_OT_SCOPE, { }, {
		{ FLT_OT_OPT_NAME, flt_ot_parse, NULL },
		{ NULL, NULL, NULL },
	}
};

INITCALL1(STG_REGISTER, flt_register_keywords, &flt_kws);

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 *
 * vi: noexpandtab shiftwidth=8 tabstop=8
 */
