/***
 * 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(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(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(retptr);

	if (type == 1) {
		retptr = invalid_char(name);
	}
	else if (type == 2) {
		retptr = invalid_domainchar(name);
	}
	else if (type == 3) {
		retptr = invalid_prefix_char(name);
	}
	else if (type == 4) {
		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(retptr);
}


/***
 * 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 > 0)) {
		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(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(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(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(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(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, 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(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(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(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(retval);

	flt_ot_current_config->tracer = flt_ot_current_tracer;

	if (flt_ot_current_tracer->id == NULL)
		FLT_OT_RETURN(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(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, 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(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(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(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(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(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(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(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, 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(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(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(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(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(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(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(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(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(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
 */
