package server

import (
	"context"
	"errors"

	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

func (b *replayBuilder) buildReplayTasks(ctx context.Context, replay *cloudv1.Replay, rctx *replayContext) error {
	if len(rctx.explicitTasks) > 0 {
		replay.Spec.Tasks = rctx.explicitTasks
		return nil
	}
	if rctx.sourceProvider == nil {
		return errors.New("source cluster is not set")
	}
	if rctx.targetProvider == nil {
		return errors.New("target cluster is not set")
	}

	strategy, err := newReplayRouteStrategy(
		rctx.sourceProvider,
		rctx.targetProvider,
	)
	if err != nil {
		return err
	}

	materials, err := strategy.BuildTaskMaterials(ctx)
	if err != nil {
		return err
	}

	materializeReplayTasks(ctx, replay, rctx, materials)
	return nil
}

func materializeReplayTasks(ctx context.Context, replay *cloudv1.Replay, rctx *replayContext, materials []replayTaskMaterial) {
	logger := tilog.WithContextL(ctx).With(zap.String("replay", replay.Name))

	replay.Spec.Tasks = make([]cloudv1.ReplayTask, 0, len(materials))
	for _, material := range materials {
		replay.Spec.Tasks = append(replay.Spec.Tasks, cloudv1.ReplayTask{
			Name:                material.name,
			TargetEndpoint:      material.targetEndpoint,
			Username:            rctx.username,
			Replicas:            rctx.replicas,
			CommandEndTime:      rctx.replayStartTime,
			StartTime:           rctx.runStartTime,
			Resources:           rctx.resources,
			SourceAuditLogAddrs: material.auditLogAddrs,
			ReplayConfigs:       buildReplicaReplayConfigs(rctx.replicas),
		})
	}

	logger.Info("Auto-generated replay Tasks", zap.Int("count", len(replay.Spec.Tasks)))
}

func buildReplicaReplayConfigs(replicas int32) []cloudv1.ReplayConfig {
	configs := make([]cloudv1.ReplayConfig, 0, replicas)
	for i := range replicas {
		configs = append(configs, cloudv1.ReplayConfig{
			ReplayerCount: replicas,
			ReplayerIndex: i,
		})
	}
	return configs
}
