//go:generate ${GOBIN}/mockgen -destination repo_mock.go -package=repo ${GO_MODULE}/pkg/service/controlplane/repo Repo
package repo

import (
	"context"

	cp "github.com/tidbcloud/devops/entity/controlplane"
)

type PatchDeployment func(current *cp.Deployment) error

type Repo interface {
	Get(ctx context.Context, id uint64) (*cp.Deployment, error)
	GetByApprovalID(ctx context.Context, approvalID uint64) (*cp.Deployment, error)
	Create(ctx context.Context, dep *cp.Deployment) (*cp.Deployment, error)
	GetAndPatch(ctx context.Context, id uint64, patch ...PatchDeployment) error
	List(ctx context.Context, scenario *cp.Scenario, phase *cp.Phase) ([]*cp.Deployment, error)
}

func NewRepo(driver DeploymentDriver) Repo {
	return &repoImpl{driver: driver}
}

type repoImpl struct {
	driver DeploymentDriver
}

func (r *repoImpl) Get(ctx context.Context, id uint64) (*cp.Deployment, error) {
	return r.driver.Load(ctx, id)
}

func (r *repoImpl) GetByApprovalID(ctx context.Context, approvalID uint64) (*cp.Deployment, error) {
	return r.driver.LoadByApprovalID(ctx, approvalID)
}

func (r *repoImpl) Create(ctx context.Context, dep *cp.Deployment) (*cp.Deployment, error) {
	return r.driver.Save(ctx, dep)
}

func (r *repoImpl) GetAndPatch(ctx context.Context, id uint64, patches ...PatchDeployment) error {
	dep, err := r.driver.Load(ctx, id)
	if err != nil {
		return err
	}
	for _, p := range patches {
		if err := p(dep); err != nil {
			return err
		}
	}
	_, err = r.driver.Save(ctx, dep)
	return err
}

func (r *repoImpl) List(ctx context.Context, scenario *cp.Scenario, phase *cp.Phase) ([]*cp.Deployment, error) {
	return r.driver.Query(ctx, scenario, phase)
}
