package repo_imp

import (
	"github.com/tidbcloud/chaos-svc/model"
	"github.com/tidbcloud/chaos-svc/pkg/domain/repo"
	"github.com/tidbcloud/pkgv2/bizerr"
	"go.buf.build/protocolbuffers/go/linuxgit/tidbcloud/base"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

func saveWithVersioning(wdb *gorm.DB, value interface{}) bizerr.BizError {
	dst, ok := value.(model.IdAndVersioning)
	if !ok {
		return bizerr.WrapGormError(wdb.Save(value).Error, "save to db")
	}

	id := dst.GetID()
	versioning := dst.GetVersioning()
	if id == 0 { // new record try to create
		return bizerr.WrapGormError(wdb.Create(value).Error, "create to db")
	} else { // try to update
		result := wdb.Model(value).Select("*").Where("versioning=?", versioning).Updates(value)
		if err := result.Error; err != nil {
			return bizerr.WrapGormError(err, "update to db")
		}
		if result.RowsAffected == 0 {
			return bizerr.New(bizerr.ErrCodeOptimisticLockConflict, "version conflict,current=%d", versioning)
		}
		return nil
	}
}

func setOrderByIntoTx(tx *gorm.DB, sorters []repo.Sorter) *gorm.DB {
	for _, sorter := range sorters {
		orderBy, desc := sorter.OrderByColumn()
		tx = tx.Order(clause.OrderByColumn{Column: clause.Column{Name: orderBy}, Desc: desc})
	}

	return tx
}

func setOffsetAndLimitIntoTx(tx *gorm.DB, pager *base.Pager) *gorm.DB {
	if pager == nil {
		return tx
	}

	offset, limit := pager2offsetAndLimit(pager)
	return tx.Offset(int(offset)).Limit(int(limit))
}

func pager2offsetAndLimit(pager *base.Pager) (offset, limit int64) {
	offset = (pager.Page - 1) * pager.PageSize
	limit = pager.PageSize

	return offset, limit
}
