package api

import (
	"context"

	relent "github.com/tidbcloud/devops/entity/release"
	"github.com/tidbcloud/devops/pkg/service"
)

type CreateChangeParam struct {
	Spec    relent.ChangeInRepo
	IsDraft bool
}

type UpdateChangeParam struct {
	Name              *string
	WindowStartAt     *int64
	WindowEndAt       *int64
	Tier              *[]relent.ChangeTier
	RiskLevel         *relent.RiskLevel
	NeedOutage        *bool
	Note              *string
	RollbackPlan      *string
	StagingTestReport *string
	Type              *relent.ChangeType

	Deployments     *[]*relent.ChangeDeployment
	ChangeItemNames *[]string
}

type GetChangeParam struct {
	WithChangeDetail bool
	WithChangeItems  bool
	WithRelease      bool
	WithApplicant    bool
	WithApplication  bool
}

type ListChangeParam struct {
	GetChangeParam

	Releases []uint64
	Status   []relent.ChangeStatus
}

type DefaultChangeParam struct {
	ReleaseID       uint64
	ApplicationName string
}

type ChangeServiceAPI interface {
	ListChanges(ctx context.Context, param ListChangeParam) ([]*relent.Change, error)
	GetChange(ctx context.Context, id uint64, param GetChangeParam) (*relent.Change, error)
	UpdateChangeBeforeDeploy(ctx context.Context, id uint64, param UpdateChangeParam) error
	CreateChange(ctx context.Context, param CreateChangeParam) (*uint64, error)
	SubmitChange(ctx context.Context, id uint64) error
	CancelChange(ctx context.Context, id uint64) error
	CloseChange(ctx context.Context, id uint64, result relent.ChangeResult, summary string) error

	// ExecuteDeployment execute a deployment of a change
	ExecuteDeployment(ctx context.Context, id uint64, order relent.ChangeDeployOrder, force bool) error
	VerifyDeployment(ctx context.Context, id uint64, order relent.ChangeDeployOrder, note string) error
	IsDeploymentReady(ctx context.Context, id uint64, order relent.ChangeDeployOrder) ([]string, error)
	// DefaultChange return a change with default fields
	DefaultChange(ctx context.Context, param DefaultChangeParam) (*relent.Change, error)
}

type ChangeService interface {
	ChangeServiceAPI

	service.RunnableService
}
