package repo

import (
	"context"

	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
	"github.com/tidbcloud/serverless-service/internal/domain/entity"
)

type ChangefeedRepo interface {
	// ListByFilter returns CDCChangefeeds that match the provided filter
	ListByFilter(ctx context.Context, filter entity.ListChangefeedsFilter) ([]*entity.CDCChangefeed, bizerr.BizError)
	// CountByFilter counts CDCs that match the provided filter
	CountByFilter(ctx context.Context, filter entity.ListChangefeedsFilter) (int64, bizerr.BizError)
	// Create creates a new CDCChangefeeds record
	Create(ctx context.Context, cdc *entity.CDCChangefeed) (*entity.CDCChangefeed, bizerr.BizError)
	// GetById gets a CDCChangefeeds by clusterId and changefeedId
	GetById(ctx context.Context, clusterId, changefeedId string) (*entity.CDCChangefeed, bizerr.BizError)
	// GetByID gets a CDCChangefeed by its globally unique ID.
	GetByID(ctx context.Context, changefeedID string) (*entity.CDCChangefeed, bizerr.BizError)
	// Start resume(update state to running) a CDCChangefeed by user
	Start(ctx context.Context, clusterId, changefeedId string) (*entity.CDCChangefeed, bizerr.BizError)
	// SyncState sync state according to the ticdc state
	SyncState(ctx context.Context, changefeed *entity.CDCChangefeed) bizerr.BizError
	// Stop stops a CDCChangefeed
	Stop(ctx context.Context, clusterId, changefeedId string) (*entity.CDCChangefeed, bizerr.BizError)
	// ChangeStateFromCreating changes the state to runnig or create_failed of CDCChangefeed from creating
	ChangeStateFromCreating(ctx context.Context, cdc *entity.CDCChangefeed) bizerr.BizError
	Delete(ctx context.Context, clusterId, changefeedId string) (*entity.CDCChangefeed, bizerr.BizError)
	// Save saves the CDCChangefeed
	Save(ctx context.Context, cdc *entity.CDCChangefeed) (*entity.CDCChangefeed, bizerr.BizError)
	// CleanByRetention cleans CDCChangefeeds that are older than retentionDays
	CleanByRetention(ctx context.Context, retentionDays int) (int64, bizerr.BizError)
	// GroupByClusterId counts CDCChangefeeds by clusterId
	GroupByClusterId(ctx context.Context) ([]*entity.ChangefeedCountByCluster, bizerr.BizError)
	// GroupByState counts CDCChangefeeds by state
	GroupByState(ctx context.Context) ([]*entity.ChangefeedStateCount, bizerr.BizError)
}

type CDCClusterRepo interface {
	// Create creates a new CDCCluster record
	Create(ctx context.Context, cluster *entity.CDCCluster) bizerr.BizError
	// GetById gets a CDCCluster by clusterId
	GetById(ctx context.Context, clusterId string) (*entity.CDCCluster, bizerr.BizError)
	// Delete delete a CDCCluster
	Delete(ctx context.Context, clusterId string) bizerr.BizError
	// IncreaseOrCreateChangefeed increases the changefeed_count by 1, or it will creata one if not exist
	// Affected rows rule: https://dev.mysql.com/doc/refman/8.4/en/insert-on-duplicate.html
	// - 0: nothing changed
	// - 1: cdc cluster is inserted
	// - 2: cdc cluster is updated
	IncreaseOrCreateChangefeed(ctx context.Context, changefeed *entity.CDCChangefeed) (int64, bizerr.BizError)
	// DecreaseChangefeed decreases the changefeed_count by 1
	DecreaseChangefeed(ctx context.Context, clusterId string) bizerr.BizError
	// ListCDCWithoutChangefeed
	ListCDCWithoutChangefeed(ctx context.Context) ([]*entity.CDCCluster, bizerr.BizError)
	// SetClusterStatusId set the statusId of the CDCCluster
	SetClusterStatusId(ctx context.Context, clusterId string, statusId uint64) bizerr.BizError
	// Update ClusterStatus updates the status of the CDCCluster
	UpdateState(ctx context.Context, clusterId string, status constant.CDCClusterState) bizerr.BizError
	// CleanByRetention cleans CDCClusters that are older than retentionDays
	CleanByRetention(ctx context.Context, retentionDays int) (int64, bizerr.BizError)
}
