package repo

import (
	"context"

	appent "github.com/tidbcloud/devops/entity/application"
	"github.com/tidbcloud/devops/entity/validation"
	"github.com/tidbcloud/devops/pkg/infra/utils/repoopt"
	"github.com/tidbcloud/devops/pkg/service/application/repo/cvt"

	"github.com/tidbcloud/pkgv2/db"
)

type ApplicationRepo interface {
	ListApplications(ctx context.Context, opts ...repoopt.Option) ([]*appent.Application, error)
	GetApplication(ctx context.Context, name string) (*appent.Application, error)
	CreateApplication(ctx context.Context, app *appent.Application) (*appent.Application, error)
	UpdateApplication(ctx context.Context, app *appent.Application) (*appent.Application, error)
	CountApplications(ctx context.Context, opts ...repoopt.Option) (int64, error)
	DeleteApplication(ctx context.Context, name string) error
}

func NewApplicationRepo(dbp db.Provider) ApplicationRepo {
	driver := &driver{
		cvter:      cvt.NewConverter(),
		dbProvider: dbp,
	}

	return &repo{
		driver: driver,
	}
}

type repo struct {
	driver Driver
}

func (r *repo) ListApplications(ctx context.Context, opts ...repoopt.Option) ([]*appent.Application, error) {
	return r.driver.Query(ctx, opts...)
}
func (r *repo) GetApplication(ctx context.Context, name string) (*appent.Application, error) {
	return r.driver.Load(ctx, name)
}
func (r *repo) CreateApplication(ctx context.Context, app *appent.Application) (*appent.Application, error) {
	err := validation.Application.Application(app)
	if err != nil {
		return nil, err
	}

	return r.driver.Save(ctx, app)
}
func (r *repo) UpdateApplication(ctx context.Context, app *appent.Application) (*appent.Application, error) {
	err := validation.Application.Application(app)
	if err != nil {
		return nil, err
	}

	return r.driver.Save(ctx, app)
}
func (r *repo) CountApplications(ctx context.Context, opts ...repoopt.Option) (int64, error) {
	return r.driver.Count(ctx, opts...)
}
func (r *repo) DeleteApplication(ctx context.Context, name string) error {
	return r.driver.Delete(ctx, name)
}
