/***
 * 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 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->uuid.u64[0]   = ha_random64();
	retptr->uuid.u64[1]   = ha_random64();
	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));

	(void)snprintf(retptr->uuid.s, sizeof(retptr->uuid.s), "%08x-%04hx-%04hx-%04hx-%012" PRIx64,
	               retptr->uuid.time_low,
	               retptr->uuid.time_mid,
	               (uint16_t)((retptr->uuid.time_hi_and_version & UINT16_C(0xfff)) | UINT16_C(0x4000)),
	               (uint16_t)(retptr->uuid.clock_seq | UINT16_C(0x8000)),
	               (uint64_t)retptr->uuid.node);

	if (flt_ot_var_register(FTL_OT_VAR_UUID, err) != -1)
		(void)flt_ot_var_set(s, FTL_OT_VAR_UUID, retptr->uuid.s, SMP_OPT_DIR_REQ, err);

	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);
				(void)flt_ot_vars_unset(rt_ctx->stream, FLT_OT_VARS_SCOPE, ctx->id, ctx->smp_opt_dir, NULL);

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