/***
 * 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"


static struct pool_head *pool_head_ot_scope_span __read_mostly = NULL;
static struct pool_head *pool_head_ot_scope_context __read_mostly = NULL;
static struct pool_head *pool_head_ot_runtime_context __read_mostly = NULL;

#ifdef USE_POOL_OT_SCOPE_SPAN
REGISTER_POOL(&pool_head_ot_scope_span, "ot_scope_span", sizeof(struct flt_ot_scope_span));
#endif
#ifdef USE_POOL_OT_SCOPE_CONTEXT
REGISTER_POOL(&pool_head_ot_scope_context, "ot_scope_context", sizeof(struct flt_ot_scope_context));
#endif
#ifdef USE_POOL_OT_RUNTIME_CONTEXT
REGISTER_POOL(&pool_head_ot_runtime_context, "ot_runtime_context", sizeof(struct flt_ot_runtime_context));
#endif


#ifdef DEBUG_OT

/***
 * NAME
 *   flt_ot_pools_info -
 *
 * ARGUMENTS
 *   This function takes no arguments.
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   This function does not return a value.
 */
void flt_ot_pools_info(void)
{
	/*
	 * In case we have some error in the configuration file,
	 * it is possible that this pool was not initialized.
	 */
#ifdef USE_POOL_BUFFER
	FLT_OT_DBG(2, "sizeof_pool(buffer) = %u", FLT_OT_DEREF(pool_head_buffer, size, 0));
#endif
#ifdef USE_TRASH_CHUNK
	FLT_OT_DBG(2, "sizeof_pool(trash) = %u", FLT_OT_DEREF(pool_head_trash, size, 0));
#endif

#ifdef USE_POOL_OT_SCOPE_SPAN
	FLT_OT_DBG(2, "sizeof_pool(ot_scope_span) = %u", pool_head_ot_scope_span->size);
#endif
#ifdef USE_POOL_OT_SCOPE_CONTEXT
	FLT_OT_DBG(2, "sizeof_pool(ot_scope_context) = %u", pool_head_ot_scope_context->size);
#endif
#ifdef USE_POOL_OT_RUNTIME_CONTEXT
	FLT_OT_DBG(2, "sizeof_pool(ot_runtime_context) = %u", pool_head_ot_runtime_context->size);
#endif
}

#endif /* DEBUG_OT */


/***
 * NAME
 *   flt_ot_runtime_context_init -
 *
 * ARGUMENTS
 *   s   -
 *   f   -
 *   err -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   -
 */
struct flt_ot_runtime_context *flt_ot_runtime_context_init(struct stream *s, struct filter *f, char **err)
{
	const struct flt_ot_conf      *conf = FLT_OT_CONF(f);
	struct buffer                  uuid;
	struct flt_ot_runtime_context *retptr = NULL;

	FLT_OT_FUNC("%p, %p, %p:%p", s, f, FLT_OT_DPTR_ARGS(err));

	retptr = flt_ot_pool_alloc(pool_head_ot_runtime_context, sizeof(*retptr), 1, err);
	if (retptr == NULL)
		FLT_OT_RETURN_PTR(retptr);

	retptr->stream        = s;
	retptr->filter        = f;
	retptr->flag_harderr  = conf->tracer->flag_harderr;
	retptr->flag_disabled = conf->tracer->flag_disabled;
	retptr->logging       = conf->tracer->logging;
	LIST_INIT(&(retptr->spans));
	LIST_INIT(&(retptr->contexts));

	uuid = b_make(retptr->uuid, sizeof(retptr->uuid), 0, 0);
	ha_generate_uuid(&uuid);

#ifdef USE_OT_VARS
	/*
	 * The HAProxy variable 'sess.ot.uuid' is registered here,
	 * after which its value is set to runtime context UUID.
	 */
	if (flt_ot_var_register(FLT_OT_VAR_UUID, err) != -1)
		(void)flt_ot_var_set(s, FLT_OT_VAR_UUID, retptr->uuid, SMP_OPT_DIR_REQ, err);
#endif

	FLT_OT_DBG_RUNTIME_CONTEXT("session context: ", retptr);

	FLT_OT_RETURN_PTR(retptr);
}


/***
 * NAME
 *   flt_ot_runtime_context_free -
 *
 * ARGUMENTS
 *   f -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   This function does not return a value.
 */
void flt_ot_runtime_context_free(struct filter *f)
{
	struct flt_ot_runtime_context *rt_ctx = f->ctx;

	FLT_OT_FUNC("%p", f);

	if (rt_ctx == NULL)
		FLT_OT_RETURN();

	FLT_OT_DBG_RUNTIME_CONTEXT("session context: ", rt_ctx);

	if (!LIST_ISEMPTY(&(rt_ctx->spans))) {
		struct timespec           ts;
		struct flt_ot_scope_span *span, *span_back;

		/* All spans should be completed at the same time. */
		(void)clock_gettime(CLOCK_MONOTONIC, &ts);

		list_for_each_entry_safe(span, span_back, &(rt_ctx->spans), list) {
			ot_span_finish(&(span->span), &ts, NULL, NULL, NULL);
			flt_ot_scope_span_free(&span);
		}
	}

	if (!LIST_ISEMPTY(&(rt_ctx->contexts))) {
		struct flt_ot_scope_context *ctx, *ctx_back;

		list_for_each_entry_safe(ctx, ctx_back, &(rt_ctx->contexts), list)
			flt_ot_scope_context_free(&ctx);
	}

	flt_ot_pool_free(pool_head_ot_runtime_context, &(f->ctx));

	FLT_OT_RETURN();
}


/***
 * NAME
 *   flt_ot_scope_span_init -
 *
 * ARGUMENTS
 *   rt_ctx     -
 *   id         -
 *   id_len     -
 *   ref_type   -
 *   ref_id     -
 *   ref_id_len -
 *   dir        -
 *   err        -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   -
 */
struct flt_ot_scope_span *flt_ot_scope_span_init(struct flt_ot_runtime_context *rt_ctx, const char *id, size_t id_len, otc_span_reference_type_t ref_type, const char *ref_id, size_t ref_id_len, uint dir, char **err)
{
	struct otc_span             *ref_span = NULL;
	struct otc_span_context     *ref_ctx = NULL;
	struct flt_ot_scope_span    *span, *retptr = NULL;
	struct flt_ot_scope_context *ctx;

	FLT_OT_FUNC("%p, \"%s\", %zu, %d, \"%s\", %zu, %u, %p:%p", rt_ctx, id, id_len, ref_type, ref_id, ref_id_len, dir, FLT_OT_DPTR_ARGS(err));

	if ((rt_ctx == NULL) || (id == NULL))
		FLT_OT_RETURN_PTR(retptr);

	list_for_each_entry(span, &(rt_ctx->spans), list)
		if ((span->id_len == id_len) && (memcmp(span->id, id, id_len) == 0)) {
			FLT_OT_DBG(2, "found span %p", span);

			FLT_OT_RETURN_PTR(span);
		}

	if (ref_id != NULL) {
		list_for_each_entry(span, &(rt_ctx->spans), list)
			if ((span->id_len == ref_id_len) && (memcmp(span->id, ref_id, ref_id_len) == 0)) {
				ref_span = span->span;

				break;
			}

		if (ref_span != NULL) {
			FLT_OT_DBG(2, "found referenced span %p", span);
		} else {
			list_for_each_entry(ctx, &(rt_ctx->contexts), list)
				if ((ctx->id_len == ref_id_len) && (memcmp(ctx->id, ref_id, ref_id_len) == 0)) {
					ref_ctx = ctx->context;

					break;
				}

			if (ref_ctx != NULL) {
				FLT_OT_DBG(2, "found referenced context %p", ctx);
			} else {
				FLT_OT_ERR("cannot find referenced span/context '%s'", ref_id);

				FLT_OT_RETURN_PTR(retptr);
			}
		}
	}

	retptr = flt_ot_pool_alloc(pool_head_ot_scope_span, sizeof(*retptr), 1, err);
	if (retptr == NULL)
		FLT_OT_RETURN_PTR(retptr);

	retptr->id          = id;
	retptr->id_len      = id_len;
	retptr->smp_opt_dir = dir;
	retptr->ref_type    = ref_type;
	retptr->ref_span    = ref_span;
	retptr->ref_ctx     = ref_ctx;
	LIST_INSERT(&(rt_ctx->spans), &(retptr->list));

	FLT_OT_DBG_SCOPE_SPAN("new span ", retptr);

	FLT_OT_RETURN_PTR(retptr);
}


/***
 * NAME
 *   flt_ot_scope_span_free -
 *
 * ARGUMENTS
 *   ptr -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   This function does not return a value.
 */
void flt_ot_scope_span_free(struct flt_ot_scope_span **ptr)
{
	FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));

	if ((ptr == NULL) || (*ptr == NULL))
		FLT_OT_RETURN();

	FLT_OT_DBG_SCOPE_SPAN("", *ptr);

	/* If the span is still active, do nothing. */
	if ((*ptr)->span != NULL) {
		FLT_OT_DBG(2, "cannot finish active span");

		FLT_OT_RETURN();
	}

	FLT_OT_LIST_DEL(&((*ptr)->list));
	flt_ot_pool_free(pool_head_ot_scope_span, (void **)ptr);

	FLT_OT_RETURN();
}


/***
 * NAME
 *   flt_ot_scope_context_init -
 *
 * ARGUMENTS
 *   rt_ctx   -
 *   tracer   -
 *   id       -
 *   id_len   -
 *   text_map -
 *   dir      -
 *   err      -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   -
 */
struct flt_ot_scope_context *flt_ot_scope_context_init(struct flt_ot_runtime_context *rt_ctx, struct otc_tracer *tracer, const char *id, size_t id_len, const struct otc_text_map *text_map, uint dir, char **err)
{
	struct otc_http_headers_reader  reader;
	struct otc_span_context        *span_ctx;
	struct flt_ot_scope_context    *retptr = NULL;

	FLT_OT_FUNC("%p, %p, \"%s\", %zu, %p, %u, %p:%p", rt_ctx, tracer, id, id_len, text_map, dir, FLT_OT_DPTR_ARGS(err));

	if ((rt_ctx == NULL) || (tracer == NULL) || (id == NULL) || (text_map == NULL))
		FLT_OT_RETURN_PTR(retptr);

	list_for_each_entry(retptr, &(rt_ctx->contexts), list)
		if ((retptr->id_len == id_len) && (memcmp(retptr->id, id, id_len) == 0)) {
			FLT_OT_DBG(2, "found context %p", retptr);

			FLT_OT_RETURN_PTR(retptr);
		}

	retptr = flt_ot_pool_alloc(pool_head_ot_scope_context, sizeof(*retptr), 1, err);
	if (retptr == NULL)
		FLT_OT_RETURN_PTR(retptr);

	span_ctx = ot_extract_http_headers(tracer, &reader, text_map, err);
	if (span_ctx == NULL) {
		flt_ot_scope_context_free(&retptr);

		FLT_OT_RETURN_PTR(retptr);
	}

	retptr->id          = id;
	retptr->id_len      = id_len;
	retptr->smp_opt_dir = dir;
	retptr->context     = span_ctx;
	LIST_INSERT(&(rt_ctx->contexts), &(retptr->list));

	FLT_OT_DBG_SCOPE_CONTEXT("new context ", retptr);

	FLT_OT_RETURN_PTR(retptr);
}


/***
 * NAME
 *   flt_ot_scope_context_free -
 *
 * ARGUMENTS
 *   ptr -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   This function does not return a value.
 */
void flt_ot_scope_context_free(struct flt_ot_scope_context **ptr)
{
	FLT_OT_FUNC("%p:%p", FLT_OT_DPTR_ARGS(ptr));

	if ((ptr == NULL) || (*ptr == NULL))
		FLT_OT_RETURN();

	FLT_OT_DBG_SCOPE_CONTEXT("", *ptr);

	if ((*ptr)->context != NULL)
		(*ptr)->context->destroy(&((*ptr)->context));

	FLT_OT_LIST_DEL(&((*ptr)->list));
	flt_ot_pool_free(pool_head_ot_scope_context, (void **)ptr);

	FLT_OT_RETURN();
}


/***
 * NAME
 *   flt_ot_scope_data_free -
 *
 * ARGUMENTS
 *   ptr -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   This function does not return a value.
 */
void flt_ot_scope_data_free(struct flt_ot_scope_data *ptr)
{
	int i;

	FLT_OT_FUNC("%p", ptr);

	if (ptr == NULL)
		FLT_OT_RETURN();

	FLT_OT_DBG_SCOPE_DATA("", ptr);

	for (i = 0; i < ptr->num_tags; i++)
		if (ptr->tags[i].value.type == otc_value_string)
			FLT_OT_FREE_VOID(ptr->tags[i].value.value.string_value);
	otc_text_map_destroy(&(ptr->baggage), OTC_TEXT_MAP_FREE_VALUE);
	for (i = 0; i < ptr->num_log_fields; i++)
		if (ptr->log_fields[i].value.type == otc_value_string)
			FLT_OT_FREE_VOID(ptr->log_fields[i].value.value.string_value);

	(void)memset(ptr, 0, sizeof(*ptr));

	FLT_OT_RETURN();
}


/***
 * NAME
 *   flt_ot_scope_finish_mark -
 *
 * ARGUMENTS
 *   rt_ctx -
 *   id     -
 *   id_len -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   -
 */
int flt_ot_scope_finish_mark(const struct flt_ot_runtime_context *rt_ctx, const char *id, size_t id_len)
{
	struct flt_ot_scope_span    *span;
	struct flt_ot_scope_context *ctx;
	int                          span_cnt = 0, ctx_cnt = 0, retval;

	FLT_OT_FUNC("%p, \"%s\", %zu", rt_ctx, id, id_len);

	if (FLT_OT_STR_CMP(FLT_OT_SCOPE_SPAN_FINISH_ALL, id, id_len)) {
		list_for_each_entry(span, &(rt_ctx->spans), list) {
			span->flag_finish = 1;
			span_cnt++;
		}

		list_for_each_entry(ctx, &(rt_ctx->contexts), list) {
			ctx->flag_finish = 1;
			ctx_cnt++;
		}

		FLT_OT_DBG(2, "marked %d span(s), %d context(s)", span_cnt, ctx_cnt);
	}
	else if (FLT_OT_STR_CMP(FLT_OT_SCOPE_SPAN_FINISH_REQ, id, id_len)) {
		list_for_each_entry(span, &(rt_ctx->spans), list)
			if (span->smp_opt_dir == SMP_OPT_DIR_REQ) {
				span->flag_finish = 1;
				span_cnt++;
			}

		list_for_each_entry(ctx, &(rt_ctx->contexts), list)
			if (ctx->smp_opt_dir == SMP_OPT_DIR_REQ) {
				ctx->flag_finish = 1;
				span_cnt++;
			}

		FLT_OT_DBG(2, "marked REQuest channel %d span(s), %d context(s)", span_cnt, ctx_cnt);
	}
	else if (FLT_OT_STR_CMP(FLT_OT_SCOPE_SPAN_FINISH_RES, id, id_len)) {
		list_for_each_entry(span, &(rt_ctx->spans), list)
			if (span->smp_opt_dir == SMP_OPT_DIR_RES) {
				span->flag_finish = 1;
				span_cnt++;
			}

		list_for_each_entry(ctx, &(rt_ctx->contexts), list)
			if (ctx->smp_opt_dir == SMP_OPT_DIR_RES) {
				ctx->flag_finish = 1;
				ctx_cnt++;
			}

		FLT_OT_DBG(2, "marked RESponse channel %d span(s), %d context(s)", span_cnt, ctx_cnt);
	}
	else {
		list_for_each_entry(span, &(rt_ctx->spans), list)
			if ((span->id_len == id_len) && (memcmp(span->id, id, id_len) == 0)) {
				span->flag_finish = 1;
				span_cnt++;

				break;
			}

		list_for_each_entry(ctx, &(rt_ctx->contexts), list)
			if ((ctx->id_len == id_len) && (memcmp(ctx->id, id, id_len) == 0)) {
				ctx->flag_finish = 1;
				ctx_cnt++;

				break;
			}

		if (span_cnt > 0)
			FLT_OT_DBG(2, "marked span '%s'", id);
		if (ctx_cnt > 0)
			FLT_OT_DBG(2, "marked context '%s'", id);
		if ((span_cnt + ctx_cnt) == 0)
			FLT_OT_DBG(2, "cannot find span/context '%s'", id);
	}

	retval = span_cnt + ctx_cnt;

	FLT_OT_RETURN_INT(retval);
}


/***
 * NAME
 *   flt_ot_scope_finish_marked -
 *
 * ARGUMENTS
 *   rt_ctx    -
 *   ts_finish -
 *
 * DESCRIPTION
 *   Finish marked spans.
 *
 * RETURN VALUE
 *   This function does not return a value.
 */
void flt_ot_scope_finish_marked(const struct flt_ot_runtime_context *rt_ctx, const struct timespec *ts_finish)
{
	struct flt_ot_scope_span    *span;
	struct flt_ot_scope_context *ctx;

	FLT_OT_FUNC("%p, %p", rt_ctx, ts_finish);

	list_for_each_entry(span, &(rt_ctx->spans), list)
		if (span->flag_finish) {
			FLT_OT_DBG_SCOPE_SPAN("finishing span ", span);

			ot_span_finish(&(span->span), ts_finish, NULL, NULL, NULL);

			span->flag_finish = 0;
		}

	list_for_each_entry(ctx, &(rt_ctx->contexts), list)
		if (ctx->flag_finish) {
			FLT_OT_DBG_SCOPE_CONTEXT("finishing context ", ctx);

			if (ctx->context != NULL)
				ctx->context->destroy(&(ctx->context));

			ctx->flag_finish = 0;
		}

	FLT_OT_RETURN();
}


/***
 * NAME
 *   flt_ot_scope_free_unused -
 *
 * ARGUMENTS
 *   rt_ctx -
 *   chn    -
 *
 * DESCRIPTION
 *   -
 *
 * RETURN VALUE
 *   This function does not return a value.
 */
void flt_ot_scope_free_unused(struct flt_ot_runtime_context *rt_ctx, struct channel *chn)
{
	FLT_OT_FUNC("%p", rt_ctx);

	if (rt_ctx == NULL)
		FLT_OT_RETURN();

	if (!LIST_ISEMPTY(&(rt_ctx->spans))) {
		struct flt_ot_scope_span *span, *span_back;

		list_for_each_entry_safe(span, span_back, &(rt_ctx->spans), list)
			if (span->span == NULL)
				flt_ot_scope_span_free(&span);
	}

	if (!LIST_ISEMPTY(&(rt_ctx->contexts))) {
		struct flt_ot_scope_context *ctx, *ctx_back;

		list_for_each_entry_safe(ctx, ctx_back, &(rt_ctx->contexts), list)
			if (ctx->context == NULL) {
				/*
				 * All headers and variables associated with
				 * the context in question should be deleted.
				 */
				(void)flt_ot_http_headers_remove(chn, ctx->id, NULL);
#ifdef USE_OT_VARS
				(void)flt_ot_vars_unset(rt_ctx->stream, FLT_OT_VARS_SCOPE, ctx->id, ctx->smp_opt_dir, NULL);
#endif

				flt_ot_scope_context_free(&ctx);
			}
	}

	FLT_OT_DBG_RUNTIME_CONTEXT("session context: ", rt_ctx);

	FLT_OT_RETURN();
}

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