package biz_changefeed

import (
	"context"

	"github.com/tidbcloud/dataflow-service-ng/app/repo/entity"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/pkgv2/db"
	"gorm.io/gorm"
)

type changefeeedSpecificationRepoImpl struct {
	dbProvider db.Provider
}

func NewChangefeedSpecificationRepo(dbProvider db.Provider) ChangefeedSpecificationRepo {
	return &changefeeedSpecificationRepoImpl{dbProvider: dbProvider}
}

// List fetches all normal changefeed instance types
func (repo *changefeeedSpecificationRepoImpl) ListChangefeedSpecification(
	ctx context.Context, filter ChangefeedSpecificationFilter) (
	[]*entity.ChangefeedSpecification, bizerr.BizError,
) {
	rdb := repo.dbProvider.ReadDB(ctx)
	tx := repo.buildTxChangefeedInstanceTypeFilter(rdb, filter)
	var instanceTypes []*entity.ChangefeedSpecification
	if err := tx.Model(&entity.ChangefeedSpecification{}).Find(&instanceTypes).Error; err != nil {
		return nil, bizerr.WrapGormError(err, "list changefeed instance type by filter, filter is %v", filter)
	}
	return instanceTypes, nil
}

func (repo *changefeeedSpecificationRepoImpl) GetChangefeedSpecification(
	ctx context.Context,
	filter ChangefeedSpecificationFilter,
) (*entity.ChangefeedSpecification, bizerr.BizError) {
	rdb := repo.dbProvider.ReadDB(ctx)
	tx := repo.buildTxChangefeedInstanceTypeFilter(rdb, filter)
	instanceType := new(entity.ChangefeedSpecification)
	if err := tx.Model(&entity.ChangefeedSpecification{}).First(instanceType).Error; err != nil {
		return nil, bizerr.WrapGormError(err, "get changefeed instance type by filter, filter is %v", filter)
	}
	return instanceType, nil
}

func (repo *changefeeedSpecificationRepoImpl) SaveChangefeedSpecification(
	ctx context.Context, instanceType *entity.ChangefeedSpecification,
) bizerr.BizError {
	wdb := repo.dbProvider.WriteDB(ctx)
	if err := wdb.Save(instanceType).Error; err != nil {
		return bizerr.WrapGormError(err, "save changefeed instance type")
	}
	return nil
}

func (repo *changefeeedSpecificationRepoImpl) buildTxChangefeedInstanceTypeFilter(tx *gorm.DB,
	filter ChangefeedSpecificationFilter,
) *gorm.DB {
	// quick hit by id
	if filter.ID != nil {
		return tx.Where("id = ?", filter.ID)
	}
	if filter.BusinessType != "" {
		tx = tx.Where("business_type = ?", filter.BusinessType)
	}
	if filter.Name != "" {
		tx = tx.Where("name = ?", filter.Name)
	}
	return tx
}
