package impl

import (
	"github.com/tidbcloud/dataflow-service/app/internal/status_matrix"
	status_matrix_impl "github.com/tidbcloud/dataflow-service/app/internal/status_matrix/impl"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
)

const (
	bizChangefeedActionCreate = "Create"
	bizChangefeedActionScale  = "Scale"
	bizChangefeedActionPause  = "Pause"
	bizChangefeedActionResume = "Resume"
	bizChangefeedActionEdit   = "Edit"
	bizChangefeedActionDelete = "Delete"
)

var bizChangefeedStatusMatrix = map[string]map[string]string{
	string(entity.BizChangefeedOperationStatusCreating): {
		bizChangefeedActionDelete: string(entity.BizChangefeedOperationStatusDeleting),
	},
	string(entity.BizChangefeedOperationStatusNormal): {
		bizChangefeedActionScale:  string(entity.BizChangefeedOperationStatusScaling),
		bizChangefeedActionPause:  string(entity.BizChangefeedOperationStatusPaused),
		bizChangefeedActionEdit:   string(entity.BizChangefeedOperationStatusNormal),
		bizChangefeedActionDelete: string(entity.BizChangefeedOperationStatusDeleting),
		// if the kernel changefeed is error state, the operation status of biz changefeed is still normal.
		// so we should allow resume operation to recover the error changefeed.
		bizChangefeedActionResume: string(entity.BizChangefeedOperationStatusNormal),
	},
	string(entity.BizChangefeedOperationStatusScaling): {
		bizChangefeedActionDelete: string(entity.BizChangefeedOperationStatusDeleting),
	},
	string(entity.BizChangefeedOperationStatusPaused): {
		bizChangefeedActionResume: string(entity.BizChangefeedOperationStatusNormal),
		bizChangefeedActionEdit:   string(entity.BizChangefeedOperationStatusPaused),
		bizChangefeedActionDelete: string(entity.BizChangefeedOperationStatusDeleting),
	},
	// This status means creation failed before the kernel changefeed was created.
	// Kernel-failed changefeeds keep the normal business status and are handled there.
	string(entity.BizChangefeedOperationStatusFailed): {
		bizChangefeedActionDelete: string(entity.BizChangefeedOperationStatusDeleting),
	},
	string(entity.BizChangefeedOperationStatusDeleting): {},
	string(entity.BizChangefeedOperationStatusDeleted):  {},
}

var bizChangefeedFriendlyActionMap = map[string]map[string]status_matrix.ActionStrategy{
	bizChangefeedActionCreate: {
		bizChangefeedActionDelete: status_matrix.Grab,
	},
	bizChangefeedActionScale: {
		bizChangefeedActionDelete: status_matrix.Grab,
	},
}

var bizChangefeedSteadyStateMatrix = map[string]string{
	string(entity.BizChangefeedOperationStatusCreating): string(entity.BizChangefeedOperationStatusNormal),
	string(entity.BizChangefeedOperationStatusScaling):  string(entity.BizChangefeedOperationStatusNormal),
	string(entity.BizChangefeedOperationStatusDeleting): string(entity.BizChangefeedOperationStatusDeleted),
}

func NewBizChangefeedStatusMatrix() status_matrix.StatusMatrix {
	return status_matrix_impl.NewStatusMatrix(
		bizChangefeedStatusMatrix,
		bizChangefeedFriendlyActionMap,
		bizChangefeedSteadyStateMatrix)
}
