/*
 * Configuration condition preprocessor
 *
 * Copyright 2000-2021 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 <haproxy/api.h>
#include <haproxy/arg.h>
#include <haproxy/cfgcond.h>
#include <haproxy/global.h>
#include <haproxy/tools.h>

/* supported condition predicates */
const struct cond_pred_kw cond_predicates[] = {
	{ "defined",                  CFG_PRED_DEFINED,              ARG1(1, STR)         },
	{ "feature",                  CFG_PRED_FEATURE,              ARG1(1, STR)         },
	{ "streq",                    CFG_PRED_STREQ,                ARG2(2, STR, STR)    },
	{ "strneq",                   CFG_PRED_STRNEQ,               ARG2(2, STR, STR)    },
	{ "version_atleast",          CFG_PRED_VERSION_ATLEAST,      ARG1(1, STR)         },
	{ "version_before",           CFG_PRED_VERSION_BEFORE,       ARG1(1, STR)         },
	{ "openssl_version_atleast",  CFG_PRED_OSSL_VERSION_ATLEAST, ARG1(1, STR)         },
	{ "openssl_version_before",   CFG_PRED_OSSL_VERSION_BEFORE,  ARG1(1, STR)         },
	{ NULL, CFG_PRED_NONE, 0 }
};

/* looks up a cond predicate matching the keyword in <str>, possibly followed
 * by a parenthesis. Returns a pointer to it or NULL if not found.
 */
const struct cond_pred_kw *cfg_lookup_cond_pred(const char *str)
{
	const struct cond_pred_kw *ret;
	int len = strcspn(str, " (");

	for (ret = &cond_predicates[0]; ret->word; ret++) {
		if (len != strlen(ret->word))
			continue;
		if (strncmp(str, ret->word, len) != 0)
			continue;
		return ret;
	}
	return NULL;
}

/* Frees <term> and its args. NULL is supported and does nothing. */
void cfg_free_cond_term(struct cfg_cond_term *term)
{
	if (!term)
		return;

	if (term->type == CCTT_PAREN) {
		cfg_free_cond_expr(term->expr);
		term->expr = NULL;
	}

	free_args(term->args);
	free(term->args);
	free(term);
}

/* Parse an indirect input text as a possible config condition term.
 * Returns <0 on parsing error, 0 if the parser is desynchronized, or >0 on
 * success. <term> is allocated and filled with the parsed info, and <text>
 * is updated on success to point to the first unparsed character, or is left
 * untouched on failure. On success, the caller must free <term> using
 * cfg_free_cond_term(). An error will be set in <err> on error, and only
 * in this case. In this case the first bad character will be reported in
 * <errptr>. <maxdepth> corresponds to the maximum recursion depth permitted,
 * it is decremented on each recursive call and the parsing will fail one
 * reaching <= 0.
 */
int cfg_parse_cond_term(const char **text, struct cfg_cond_term **term, char **err, const char **errptr, int maxdepth)
{
	struct cfg_cond_term *t;
	const char *in = *text;
	const char *end_ptr;
	int err_arg;
	int nbargs;
	char *end;
	long val;

	while (*in == ' ' || *in == '\t')
		in++;

	if (!*in) /* empty term does not parse */
		return 0;

	*term = NULL;
	if (maxdepth <= 0)
		goto fail0;

	t = *term = calloc(1, sizeof(**term));
	if (!t) {
		memprintf(err, "memory allocation error while parsing conditional expression '%s'", *text);
		goto fail1;
	}

	t->type = CCTT_NONE;
	t->args = NULL;
	t->neg  = 0;

	/* !<term> negates the term. White spaces permitted */
	while (*in == '!') {
		t->neg = !t->neg;
		do { in++; } while (*in == ' ' || *in == '\t');
	}

	val = strtol(in, &end, 0);
	if (end != in) {
		t->type = val ? CCTT_TRUE : CCTT_FALSE;
		*text = end;
		return 1;
	}

	/* Try to parse '(' EXPR ')' */
	if (*in == '(') {
		int ret;

		t->type = CCTT_PAREN;
		t->args = NULL;

		do { in++; } while (*in == ' ' || *in == '\t');
		ret = cfg_parse_cond_expr(&in, &t->expr, err, errptr, maxdepth - 1);
		if (ret == -1)
			goto fail2;
		if (ret == 0)
			goto fail0;

		/* find the closing ')' */
		while (*in == ' ' || *in == '\t')
			in++;
		if (*in != ')') {
			memprintf(err, "expected ')' after conditional expression '%s'", *text);
			goto fail1;
		}
		do { in++; } while (*in == ' ' || *in == '\t');
		*text = in;
		return 1;
	}

	/* below we'll likely all make_arg_list() so we must return only via
	 * the <done> label which frees the arg list.
	 */
	t->pred = cfg_lookup_cond_pred(in);
	if (t->pred) {
		t->type = CCTT_PRED;
		nbargs = make_arg_list(in + strlen(t->pred->word), -1,
		                       t->pred->arg_mask, &t->args, err,
		                       &end_ptr, &err_arg, NULL);
		if (nbargs < 0) {
			memprintf(err, "%s in argument %d of predicate '%s' used in conditional expression", *err, err_arg, t->pred->word);
			if (errptr)
				*errptr = end_ptr;
			goto fail2;
		}
		*text = end_ptr;
		return 1;
	}

 fail0:
	memprintf(err, "unparsable conditional expression '%s'", *text);
 fail1:
	if (errptr)
		*errptr = *text;
 fail2:
	cfg_free_cond_term(*term);
	*term = NULL;
	return -1;
}

/* evaluate a condition term on a .if/.elif line. The condition was already
 * parsed in <term>. Returns -1 on error (in which case err is filled with a
 * message, and only in this case), 0 if the condition is false, 1 if it's
 * true.
 */
int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err)
{
	int ret = -1;

	if (term->type == CCTT_FALSE)
		ret = 0;
	else if (term->type == CCTT_TRUE)
		ret = 1;
	else if (term->type == CCTT_PRED) {
		/* here we know we have a valid predicate with valid arguments
		 * placed in term->args (which the caller will free).
		 */
		switch (term->pred->prd) {
		case CFG_PRED_DEFINED:  // checks if arg exists as an environment variable
			ret = getenv(term->args[0].data.str.area) != NULL;
			break;

		case CFG_PRED_FEATURE: { // checks if the arg matches an enabled feature
			const char *p;

			ret = 0; // assume feature not found
			for (p = build_features; (p = strstr(p, term->args[0].data.str.area)); p++) {
				if (p > build_features &&
				    (p[term->args[0].data.str.data] == ' ' ||
				     p[term->args[0].data.str.data] == 0)) {
					if (*(p-1) == '+') {       // e.g. "+OPENSSL"
						ret = 1;
						break;
					}
					else if (*(p-1) == '-') {  // e.g. "-OPENSSL"
						ret = 0;
						break;
					}
					/* it was a sub-word, let's restart from next place */
				}
			}
			break;
		}
		case CFG_PRED_STREQ:    // checks if the two arg are equal
			ret = strcmp(term->args[0].data.str.area, term->args[1].data.str.area) == 0;
			break;

		case CFG_PRED_STRNEQ:   // checks if the two arg are different
			ret = strcmp(term->args[0].data.str.area, term->args[1].data.str.area) != 0;
			break;

		case CFG_PRED_VERSION_ATLEAST: // checks if the current version is at least this one
			ret = compare_current_version(term->args[0].data.str.area) <= 0;
			break;

		case CFG_PRED_VERSION_BEFORE:  // checks if the current version is older than this one
			ret = compare_current_version(term->args[0].data.str.area) > 0;
			break;

		case CFG_PRED_OSSL_VERSION_ATLEAST: { // checks if the current openssl version is at least this one
			int opensslret = openssl_compare_current_version(term->args[0].data.str.area);

			if (opensslret < -1) /* can't parse the string or no openssl available */
				ret = -1;
			else
				ret = opensslret <= 0;
			break;
		}
		case CFG_PRED_OSSL_VERSION_BEFORE: { // checks if the current openssl version is older than this one
			int opensslret = openssl_compare_current_version(term->args[0].data.str.area);

			if (opensslret < -1) /* can't parse the string or no openssl available */
				ret = -1;
			else
				ret = opensslret > 0;
			break;
		}
		default:
			memprintf(err, "internal error: unhandled conditional expression predicate '%s'", term->pred->word);
			break;
		}
	}
	else if (term->type == CCTT_PAREN) {
		ret = cfg_eval_cond_expr(term->expr, err);
	}
	else {
		memprintf(err, "internal error: unhandled condition term type %d", (int)term->type);
	}

	if (ret >= 0 && term->neg)
		ret = !ret;
	return ret;
}


/* Frees <expr> and its terms and args. NULL is supported and does nothing. */
void cfg_free_cond_and(struct cfg_cond_and *expr)
{
	struct cfg_cond_and *prev;

	while (expr) {
		cfg_free_cond_term(expr->left);
		prev = expr;
		expr = expr->right;
		free(prev);
	}
}

/* Frees <expr> and its terms and args. NULL is supported and does nothing. */
void cfg_free_cond_expr(struct cfg_cond_expr *expr)
{
	struct cfg_cond_expr *prev;

	while (expr) {
		cfg_free_cond_and(expr->left);
		prev = expr;
		expr = expr->right;
		free(prev);
	}
}

/* Parse an indirect input text as a possible config condition sub-expr.
 * Returns <0 on parsing error, 0 if the parser is desynchronized, or >0 on
 * success. <expr> is filled with the parsed info, and <text> is updated on
 * success to point to the first unparsed character, or is left untouched
 * on failure. On success, the caller will have to free all lower-level
 * allocated structs using cfg_free_cond_expr(). An error will be set in
 * <err> on error, and only in this case. In this case the first bad
 * character will be reported in <errptr>. <maxdepth> corresponds to the
 * maximum recursion depth permitted, it is decremented on each recursive
 * call and the parsing will fail one reaching <= 0.
 */
int cfg_parse_cond_and(const char **text, struct cfg_cond_and **expr, char **err, const char **errptr, int maxdepth)
{
	struct cfg_cond_and *e;
	const char *in = *text;
	int ret = -1;

	if (!*in) /* empty expr does not parse */
		return 0;

	*expr = NULL;
	if (maxdepth <= 0) {
		memprintf(err, "unparsable conditional sub-expression '%s'", in);
		if (errptr)
			*errptr = in;
		goto done;
	}

	e = *expr = calloc(1, sizeof(**expr));
	if (!e) {
		memprintf(err, "memory allocation error while parsing conditional expression '%s'", *text);
		goto done;
	}

	ret = cfg_parse_cond_term(&in, &e->left, err, errptr, maxdepth - 1);
	if (ret == -1) // parse error, error already reported
		goto done;

	if (ret == 0) {
		/* ret == 0, no other way to parse this */
		memprintf(err, "unparsable conditional sub-expression '%s'", in);
		if (errptr)
			*errptr = in;
		ret = -1;
		goto done;
	}

	/* ret=1, we have a term in the left hand set */

	/* find an optional '&&' */
	while (*in == ' ' || *in == '\t')
		in++;

	*text = in;
	if (in[0] != '&' || in[1] != '&')
		goto done;

	/* we have a '&&', let's parse the right handset's subexp */
	in += 2;
	while (*in == ' ' || *in == '\t')
		in++;

	ret = cfg_parse_cond_and(&in, &e->right, err, errptr, maxdepth - 1);
	if (ret > 0)
		*text = in;
 done:
	if (ret < 0) {
		cfg_free_cond_and(*expr);
		*expr = NULL;
	}
	return ret;
}

/* Parse an indirect input text as a possible config condition term.
 * Returns <0 on parsing error, 0 if the parser is desynchronized, or >0 on
 * success. <expr> is filled with the parsed info, and <text> is updated on
 * success to point to the first unparsed character, or is left untouched
 * on failure. On success, the caller will have to free all lower-level
 * allocated structs using cfg_free_cond_expr(). An error will be set in
 * <err> on error, and only in this case. In this case the first bad
 * character will be reported in <errptr>. <maxdepth> corresponds to the
 * maximum recursion depth permitted, it is decremented on each recursive call
 * and the parsing will fail one reaching <= 0.
 */
int cfg_parse_cond_expr(const char **text, struct cfg_cond_expr **expr, char **err, const char **errptr, int maxdepth)
{
	struct cfg_cond_expr *e;
	const char *in = *text;
	int ret = -1;

	if (!*in) /* empty expr does not parse */
		return 0;

	*expr = NULL;
	if (maxdepth <= 0) {
		memprintf(err, "unparsable conditional expression '%s'", in);
		if (errptr)
			*errptr = in;
		goto done;
	}

	e = *expr = calloc(1, sizeof(**expr));
	if (!e) {
		memprintf(err, "memory allocation error while parsing conditional expression '%s'", *text);
		goto done;
	}

	ret = cfg_parse_cond_and(&in, &e->left, err, errptr, maxdepth - 1);
	if (ret == -1) // parse error, error already reported
		goto done;

	if (ret == 0) {
		/* ret == 0, no other way to parse this */
		memprintf(err, "unparsable conditional expression '%s'", in);
		if (errptr)
			*errptr = in;
		ret = -1;
		goto done;
	}

	/* ret=1, we have a sub-expr in the left hand set */

	/* find an optional '||' */
	while (*in == ' ' || *in == '\t')
		in++;

	*text = in;
	if (in[0] != '|' || in[1] != '|')
		goto done;

	/* we have a '||', let's parse the right handset's subexp */
	in += 2;
	while (*in == ' ' || *in == '\t')
		in++;

	ret = cfg_parse_cond_expr(&in, &e->right, err, errptr, maxdepth - 1);
	if (ret > 0)
		*text = in;
 done:
	if (ret < 0) {
		cfg_free_cond_expr(*expr);
		*expr = NULL;
	}
	return ret;
}

/* evaluate an sub-expression on a .if/.elif line. The expression is valid and
 * was already parsed in <expr>. Returns -1 on error (in which case err is
 * filled with a message, and only in this case), 0 if the condition is false,
 * 1 if it's true.
 */
int cfg_eval_cond_and(struct cfg_cond_and *expr, char **err)
{
	int ret;

	/* AND: loop on terms and sub-exp's terms as long as they're TRUE
	 * (stop on FALSE and ERROR).
	 */
	while ((ret = cfg_eval_cond_term(expr->left, err)) > 0 && expr->right)
		expr = expr->right;
	return ret;
}

/* evaluate an expression on a .if/.elif line. The expression is valid and was
 * already parsed in <expr>. Returns -1 on error (in which case err is filled
 * with a message, and only in this case), 0 if the condition is false, 1 if
 * it's true.
 */
int cfg_eval_cond_expr(struct cfg_cond_expr *expr, char **err)
{
	int ret;

	/* OR: loop on sub-exps as long as they're FALSE (stop on TRUE and ERROR) */
	while ((ret = cfg_eval_cond_and(expr->left, err)) == 0 && expr->right)
		expr = expr->right;
	return ret;
}

/* evaluate a condition on a .if/.elif line. The condition is already tokenized
 * in <err>. Returns -1 on error (in which case err is filled with a message,
 * and only in this case), 0 if the condition is false, 1 if it's true. If
 * <errptr> is not NULL, it's set to the first invalid character on error.
 */
int cfg_eval_condition(char **args, char **err, const char **errptr)
{
	struct cfg_cond_expr *expr = NULL;
	const char *text = args[0];
	int ret = -1;

	if (!*text) /* note: empty = false */
		return 0;

	ret = cfg_parse_cond_expr(&text, &expr, err, errptr, MAX_CFG_RECURSION);
	if (ret != 0) {
		if (ret == -1) // parse error, error already reported
			goto done;
		while (*text == ' ' || *text == '\t')
			text++;

		if (*text) {
			ret = -1;
			memprintf(err, "unexpected character '%c' at the end of conditional expression '%s'",
				  *text, args[0]);
			goto fail;
		}

		ret = cfg_eval_cond_expr(expr, err);
		goto done;
	}

	/* ret == 0, no other way to parse this */
	ret = -1;
	memprintf(err, "unparsable conditional expression '%s'", args[0]);
 fail:
	if (errptr)
		*errptr = text;
 done:
	cfg_free_cond_expr(expr);
	return ret;
}
