//nolint:gomnd
package snapshot

import (
	"github.com/shiningrush/fastflow/pkg/entity"
	"github.com/shiningrush/fastflow/pkg/entity/run"
	"github.com/tidbcloud/dataflow-service/app/container"
	"github.com/tidbcloud/dataflow-service/app/workflow"
	backup_base "github.com/tidbcloud/dataflow-service/app/workflow/action/backup/base"
	backup_create "github.com/tidbcloud/dataflow-service/app/workflow/action/backup/snapshot/create"
	backup_del "github.com/tidbcloud/dataflow-service/app/workflow/action/backup/snapshot/del"
)

//nolint:funlen
func GetCreateDag() (*entity.Dag, []run.Action) {
	base := backup_base.NewBaseAction(
		container.Global().TransProvider,
		container.Global().BackupRepo,
		container.Global().BackupScheduleRepo,
		container.Global().LogBackupRepo,
		container.Global().BackupRegionalFacade,
		container.Global().ClusterJobModel,
		container.Global().MgmtSvcGrpcClient,
		container.Global().PitBackupSwitchRepo,
		container.Global().FeatureGate,
	)

	actions := []run.Action{
		backup_create.NewAddBucketPolicyAction(
			base, container.Global().BucketModelProxy, container.Global().TiDBClusterInfraClient),
		backup_create.NewInitBackupConfigAction(
			base, container.Global().ConfigCenterManager, container.Global().TiDBClusterInfraClient),
		backup_create.NewCreateInfraAction(
			base, container.Global().Encryptor, container.Global().ConfigCenterManager,
			container.Global().BucketRepo, container.Global().TiDBClusterInfraClient),
		backup_create.NewSyncInfraStatusAction(base),
		backup_del.NewDeleteFinalStateSnapshotBackupWorkloadAction(base),
		backup_create.NewCleanFailedBackupStorage(base, container.Global().WorkflowModel),
		backup_create.NewFinalAction(base),
	}
	dag := &entity.Dag{
		BaseInfo: entity.BaseInfo{
			ID: workflow.DagCreateSnapshotBackup,
		},
		Name: workflow.DagCreateSnapshotBackup,
		Vars: entity.DagVars{
			workflow.KeyBackupID: {},
		},
		Status: entity.DagStatusNormal,
		Tasks: []entity.Task{
			{
				ID:          workflow.ActionAddBucketPolicyForSnapshotBackup,
				ActionName:  workflow.ActionAddBucketPolicyForSnapshotBackup,
				TimeoutSecs: 3 * 60,
			},
			{
				ID:          workflow.ActionInitBackupConfig,
				ActionName:  workflow.ActionInitBackupConfig,
				DependOn:    []string{workflow.ActionAddBucketPolicyForSnapshotBackup},
				TimeoutSecs: 3 * 60,
			},
			{
				ID:          workflow.ActionCreateSnapshotBackupCR,
				ActionName:  workflow.ActionCreateSnapshotBackupCR,
				DependOn:    []string{workflow.ActionInitBackupConfig},
				TimeoutSecs: 3 * 60,
			},
			{
				ID:         workflow.ActionSyncSnapshotBackupCRStatus,
				ActionName: workflow.ActionSyncSnapshotBackupCRStatus,
				DependOn:   []string{workflow.ActionCreateSnapshotBackupCR},
				// 36h: dataplane TiKV rolling restarts/maintenance can delay the BR pod
				// for many hours before it even starts running (observed 12h gaps), so
				// 24h is too tight for large clusters and routinely makes this DAG abort
				// before BR finishes.
				TimeoutSecs: 60 * 60 * 36,
			},
			{
				ID:          workflow.ActionDeleteFinalStateSnapshotBackupWorkload,
				ActionName:  workflow.ActionDeleteFinalStateSnapshotBackupWorkload,
				DependOn:    []string{workflow.ActionSyncSnapshotBackupCRStatus},
				TimeoutSecs: 3 * 60,
			},
			{
				ID:          workflow.ActionCleanFailedSnapshotBackupStorage,
				ActionName:  workflow.ActionCleanFailedSnapshotBackupStorage,
				DependOn:    []string{workflow.ActionDeleteFinalStateSnapshotBackupWorkload},
				TimeoutSecs: 3 * 60,
			},
			{
				ID:          workflow.ActionSnapshotBackupCreationFinalStep,
				ActionName:  workflow.ActionSnapshotBackupCreationFinalStep,
				DependOn:    []string{workflow.ActionCleanFailedSnapshotBackupStorage},
				TimeoutSecs: 3 * 60,
			},
		},
	}
	return dag, actions
}

func GetWeeklyCreateDag() (*entity.Dag, []run.Action) {
	dag, actions := GetCreateDag()
	dag.ID = workflow.DagCreateWeeklySnapshotBackup
	dag.Name = workflow.DagCreateWeeklySnapshotBackup
	for i := range dag.Tasks {
		if dag.Tasks[i].ID == workflow.ActionSyncSnapshotBackupCRStatus {
			dag.Tasks[i].TimeoutSecs = 60 * 60 * 24 * 2
			break
		}
	}
	return dag, actions
}
