package agent

import (
	"context"
	"log/slog"
	"net"

	"github.com/prometheus/client_golang/prometheus"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/module/observability"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/tool/nettool"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/tool/tlstool"
)

type Factory struct {
	LogLevel      *slog.LevelVar
	GRPCLogLevel  *slog.LevelVar
	Gatherer      prometheus.Gatherer
	Registerer    prometheus.Registerer
	ListenNetwork string
	ListenAddress string
	CertFile      string
	KeyFile       string
}

func (f *Factory) IsProducingLeaderModules() bool {
	return false
}

func (f *Factory) Name() string {
	return observability.ModuleName
}

func (f *Factory) GetListenerFn() (func(context.Context) (net.Listener, error), error) {
	tlsConfig, err := tlstool.MaybeServerConfig(f.CertFile, f.KeyFile)
	if err != nil {
		return nil, err
	}
	var listener func(context.Context) (net.Listener, error)
	if tlsConfig != nil {
		listener = func(ctx context.Context) (net.Listener, error) {
			return nettool.TLSListenWithOSTCPKeepAlive(ctx, f.ListenNetwork, f.ListenAddress, tlsConfig)
		}
	} else {
		listener = func(ctx context.Context) (net.Listener, error) {
			return nettool.ListenWithOSTCPKeepAlive(ctx, f.ListenNetwork, f.ListenAddress)
		}
	}
	return listener, nil
}

func ValidateLogLevel(val string) error {
	var l slog.Level
	return l.UnmarshalText([]byte(val))
}
