package server

import (
	"context"

	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/tool/logz"
	"go.temporal.io/sdk/interceptor"
	tlog "go.temporal.io/sdk/log"
	"go.temporal.io/sdk/workflow"
)

type loggerInterceptor struct {
	interceptor.WorkerInterceptorBase
}

func (w *loggerInterceptor) InterceptActivity(ctx context.Context, next interceptor.ActivityInboundInterceptor) interceptor.ActivityInboundInterceptor {
	i := &loggerActivityInboundInterceptor{
		ActivityInboundInterceptorBase: interceptor.ActivityInboundInterceptorBase{Next: next},
		root:                           w,
	}
	return i
}

type loggerActivityInboundInterceptor struct {
	interceptor.ActivityInboundInterceptorBase
	root *loggerInterceptor
}

func (a *loggerActivityInboundInterceptor) Init(outbound interceptor.ActivityOutboundInterceptor) error {
	i := &loggerActivityOutboundInterceptor{
		ActivityOutboundInterceptorBase: interceptor.ActivityOutboundInterceptorBase{Next: outbound},
		root:                            a.root,
	}
	return a.Next.Init(i)
}

type loggerActivityOutboundInterceptor struct {
	interceptor.ActivityOutboundInterceptorBase
	root *loggerInterceptor
}

func (a *loggerActivityOutboundInterceptor) GetLogger(ctx context.Context) tlog.Logger {
	logger := a.Next.GetLogger(ctx)

	values, ok := ctx.Value(contextPropagatorKey).(contextPropagatorValues)
	if !ok {
		return logger
	}

	logger = tlog.With(logger,
		logz.ProjectIDN(values.ProjectID), logz.EventID(values.EventID), logz.EventType(values.EventType))
	return logger
}

func (w *loggerInterceptor) InterceptWorkflow(ctx workflow.Context, next interceptor.WorkflowInboundInterceptor) interceptor.WorkflowInboundInterceptor {
	i := &loggerWorkflowInboundInterceptor{
		WorkflowInboundInterceptorBase: interceptor.WorkflowInboundInterceptorBase{Next: next},
		root:                           w,
	}
	return i
}

type loggerWorkflowInboundInterceptor struct {
	interceptor.WorkflowInboundInterceptorBase
	root *loggerInterceptor
}

func (w *loggerWorkflowInboundInterceptor) Init(outbound interceptor.WorkflowOutboundInterceptor) error {
	i := &loggerWorkflowOutboundInterceptor{
		WorkflowOutboundInterceptorBase: interceptor.WorkflowOutboundInterceptorBase{Next: outbound},
		root:                            w.root,
	}
	return w.Next.Init(i)
}

type loggerWorkflowOutboundInterceptor struct {
	interceptor.WorkflowOutboundInterceptorBase
	root *loggerInterceptor
}

func (w *loggerWorkflowOutboundInterceptor) GetLogger(ctx workflow.Context) tlog.Logger {
	logger := w.Next.GetLogger(ctx)

	values, ok := ctx.Value(contextPropagatorKey).(contextPropagatorValues)
	if !ok {
		return logger
	}

	logger = tlog.With(logger,
		logz.ProjectIDN(values.ProjectID), logz.EventID(values.EventID), logz.EventType(values.EventType))
	return logger
}
