package importrepo

import (
	"context"

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

// ImportRepoImpl implements ImportRepo.
type ImportRepoImpl struct {
	dbProvider db.Provider
}

// NewImportRepoImpl creates a new ImportRepoImpl as an ImportRepo.
func NewImportRepoImpl(dbProvider db.Provider) ImportRepo {
	return &ImportRepoImpl{
		dbProvider: dbProvider,
	}
}

// Load returns the import with the given id.
// It implements ImportRepo interface.
func (r *ImportRepoImpl) Load(ctx context.Context, id uint64) (*entity.Import, bizerr.BizError) {
	rdb := r.dbProvider.ReadDB(ctx)
	var imp entity.Import
	if err := entity.NewImportQuerySet(rdb).IDEq(entity.ID(id)).One(&imp); err != nil {
		return nil, bizerr.WrapGormError(err, "loading import entity has errors")
	}
	return &imp, nil
}

// List returns all imports that match a specified filter.
// It implements ImportRepo interface.
func (r *ImportRepoImpl) List(ctx context.Context, ops ...ImportFilterOp) ([]entity.Import, bizerr.BizError) {
	rdb := r.dbProvider.ReadDB(ctx)
	qs := entity.NewImportQuerySet(rdb)
	for _, op := range ops {
		qs = op(qs)
	}

	var imports []entity.Import
	if err := qs.All(&imports); err != nil {
		return nil, bizerr.WrapGormError(err, "listing imports has errors")
	}
	return imports, nil
}

// Count returns the number of imports that match a specified filter.
// It implements ImportRepo interface.
func (r *ImportRepoImpl) Count(ctx context.Context, ops ...ImportFilterOp) (int64, bizerr.BizError) {
	rdb := r.dbProvider.ReadDB(ctx)
	qs := entity.NewImportQuerySet(rdb)
	for _, op := range ops {
		qs = op(qs)
	}

	cnt, err := qs.Count()
	if err != nil {
		return -1, bizerr.WrapGormError(err, "counting imports has errors")
	}
	return cnt, nil
}
