package agent

import (
	"context"
	"log/slog"

	"github.com/robfig/cron/v3"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/module/modagent"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/tool/syncz"
	"k8s.io/client-go/kubernetes"
)

type workerFactory struct {
	log                       *slog.Logger
	api                       modagent.API
	kubeClientset             kubernetes.Interface
	gitlabAgentNamespace      string
	gitlabAgentServiceAccount string
	ocsServiceAccountName     string
}

func (f *workerFactory) New(cfg configurationToUpdateData) syncz.Worker {
	config := cfg.containerScanningConfig
	if config == nil {
		return syncz.WorkerFunc(func(ctx context.Context) {}) // do nothing
	}

	cadence, _ := cron.ParseStandard(config.Cadence)

	var targetNamespaces []string
	if config.VulnerabilityReport != nil {
		targetNamespaces = config.VulnerabilityReport.Namespaces
	}

	persistOcsStatus := false
	if config.PersistOcsStatus != nil {
		persistOcsStatus = *config.PersistOcsStatus
	}

	scanner := newScanner(
		f.log,
		f.kubeClientset,
		f.gitlabAgentNamespace,
		cfg.agentKey,
		config.ResourceRequirements,
		targetNamespaces,
		persistOcsStatus,
		config.ScannerTimeout.AsDuration(),
		config.ReportMaxSize,
		config.VulnerabilityReport.ResourceTypes,
	)

	namespaceScanner := newNamespaceScanner(
		f.kubeClientset,
		f.gitlabAgentNamespace,
		f.gitlabAgentServiceAccount,
		cfg.agentKey,
		f.ocsServiceAccountName,
		config.TrivyK8SWrapperImage,
		config.ScannerTimeout.AsDuration(),
		*config.DeleteReportArtifact,
	)

	reporter := newReporter(f.log, f.api)

	return &schedulerWorker{
		job: &scanJob{
			log:              f.log,
			scanner:          scanner,
			namespaceScanner: namespaceScanner,
			reporter:         reporter,
		},
		cadence: cadence,
	}
}
