package repo

import (
	"context"
	"time"

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

type BackupJobRepo interface {
	Delete(ctx context.Context, expireDay int) bizerr.BizError
}

type BackupScheduleRepo interface {
	List(ctx context.Context, options entity.ListBackupScheduleOptions) ([]*entity.BackupSchedule, bizerr.BizError)
	Create(ctx context.Context, schedule *entity.BackupSchedule) bizerr.BizError
	DeleteByClusterID(ctx context.Context, clusterID string) bizerr.BizError
	UpdateRetentionByClusterID(ctx context.Context, retention int, clusterID string) bizerr.BizError
	Save(ctx context.Context, schedule *entity.BackupSchedule) (*entity.BackupSchedule, bizerr.BizError)
	CleanDeletedWithoutBackup(
		ctx context.Context,
		expireTimeGte time.Time,
		limit int,
	) (int64, bizerr.BizError)
	// used by sync worker, delete after sync done
	Count(ctx context.Context) (int64, bizerr.BizError)
	BatchAdd(ctx context.Context, schedule []*entity.BackupSchedule) bizerr.BizError
	UpdateKubernetesByClusterID(ctx context.Context, clusterId, kubernetes string) bizerr.BizError
}

type BackupScheduleHistoryRepo interface {
	GetVirtualizationCutover(ctx context.Context) (time.Time, bizerr.BizError)
	ArchiveCurrentSchedule(
		ctx context.Context,
		schedule *entity.BackupSchedule,
		validTo time.Time,
		deletedAt *time.Time,
	) bizerr.BizError
	MarkDeleted(ctx context.Context, clusterID string, deletedAt time.Time) bizerr.BizError
	List(
		ctx context.Context,
		options *entity.ListBackupScheduleHistoryOptions,
	) ([]*entity.BackupScheduleHistory, bizerr.BizError)
	DeleteExpired(ctx context.Context, now time.Time, limit int) (int64, bizerr.BizError)
}

type UserBackupRepo interface {
	Delete(ctx context.Context, options entity.UserBackupDeleteOptions) bizerr.BizError
	DeleteByBackupId(ctx context.Context, backupId string) bizerr.BizError
	GetByClusterIdAndBackupId(ctx context.Context, clusterId, backupId string) (*entity.UserBackup, bizerr.BizError)
	List(ctx context.Context, options *entity.ListUserBackupOptions) ([]*entity.UserBackup, bizerr.BizError)
	Count(ctx context.Context, options *entity.ListUserBackupOptions) (int64, bizerr.BizError)
	GetByBackupId(ctx context.Context, backupId string) (*entity.UserBackup, bizerr.BizError)
	ListDeletedClustersWithBackup(
		ctx context.Context,
		options *entity.ListRecycledInstanceOptions,
	) ([]*entity.RecycledInstance, bizerr.BizError)
}

type BackupTombstoneRepo interface {
	Create(ctx context.Context, tombstone *entity.BackupTombstone) bizerr.BizError
	List(ctx context.Context, options entity.ListBackupTombstoneOptions) ([]*entity.BackupTombstone, bizerr.BizError)
	Exists(ctx context.Context, clusterID string, scheduleTime time.Time) (bool, bizerr.BizError)
	Delete(ctx context.Context, options entity.BackupTombstoneDeleteOptions) (int64, bizerr.BizError)
}

type PhysicalBackupSlotRepo interface {
	List(ctx context.Context, keys []entity.PhysicalBackupSlotKey) ([]*entity.PhysicalBackupSlot, bizerr.BizError)
	ListByBackupTime(
		ctx context.Context,
		scopes []entity.PhysicalBackupSlotScope,
		backupTimeGte time.Time,
	) ([]*entity.PhysicalBackupSlot, bizerr.BizError)
	Get(
		ctx context.Context,
		provider, region, kubernetes string,
		slotTime time.Time,
	) (*entity.PhysicalBackupSlot, bizerr.BizError)
	GetLatest(ctx context.Context, provider, region, kubernetes string) (*entity.PhysicalBackupSlot, bizerr.BizError)
	BatchUpsert(ctx context.Context, slots []*entity.PhysicalBackupSlot) bizerr.BizError
	DeleteExpired(ctx context.Context, before time.Time, limit int) (int64, bizerr.BizError)
}

type RestoreJobRepo interface {
	Create(ctx context.Context, restore *entity.RestoreJob) bizerr.BizError
	List(ctx context.Context, options entity.ListRestoreJobOptions) ([]*entity.RestoreJob, bizerr.BizError)
	Count(ctx context.Context, options entity.ListRestoreJobOptions) (int64, bizerr.BizError)
	Save(ctx context.Context, restore *entity.RestoreJob) bizerr.BizError
	GroupByState(ctx context.Context) ([]*entity.RestoreJobStateCount, bizerr.BizError)
}

type BackupScheduleCheckJobRepo interface {
	Create(ctx context.Context, backupScheduleCheckJob *entity.BackupScheduleCheckJob) bizerr.BizError
	Save(
		ctx context.Context,
		backupScheduleCheckJob *entity.BackupScheduleCheckJob,
	) (*entity.BackupScheduleCheckJob, bizerr.BizError)
	Get(ctx context.Context, date string) (*entity.BackupScheduleCheckJob, bizerr.BizError)
}
