package action

import (
	"context"

	userv1 "github.com/tidbcloud/aisupport/packages/sdk-go/contracts/api/core-server/user/v1"
	"github.com/tidbcloud/devops/entity/event"
	relent "github.com/tidbcloud/devops/entity/release"
	"github.com/tidbcloud/devops/pkg/infra/clients/eecli"
	"github.com/tidbcloud/devops/pkg/infra/clients/fadcli"
	"github.com/tidbcloud/devops/pkg/infra/clients/larkcli"
	"github.com/tidbcloud/devops/pkg/infra/config"
	"github.com/tidbcloud/devops/pkg/service/application"
	apprsvcapi "github.com/tidbcloud/devops/pkg/service/approval/api"
	ghsvc "github.com/tidbcloud/devops/pkg/service/github"
	relsvcapi "github.com/tidbcloud/devops/pkg/service/release/api"
	"github.com/tidbcloud/devops/pkg/service/release/repo"

	"github.com/go-logr/logr"
)

// Objects caches some objects that are used by action.
type Objects struct {
	// OriginChange is the original change object.
	//
	// NOTE: **DO NOT** modify it.
	OriginChange *relent.ChangeInRepo
	// Change is the copied change object that is used in action except `actionCreateChange`.
	// NOTE: **DO NOT** modify it directly, use `ActionContext.PatchChange` instead.
	Change *relent.ChangeInRepo
	// EventDetail contains the event detail of the change and is set by actions.
	EventDetail *event.ChangeEventDetail
}

type Components struct {
	Conf               config.ReleaseSerivceConfig
	Logger             logr.Logger
	UserService        userv1.UserServiceClient
	ApplicationService application.ApplicationService
	ApprovalService    apprsvcapi.ApprovalServiceAPI
	ReleaseService     relsvcapi.ReleaseServiceAPI
	GithubService      ghsvc.GithubServiceAPI
	ChangeRepo         repo.Repo
	LarkClient         *larkcli.LarkClient
	FADClient          fadcli.Client
	EEClient           eecli.Client
}

type ActionContext struct {
	context.Context
	Components
	Objects
}

// PatchChange use the original change to patch the change.
func (a *ActionContext) PatchChange(ctx context.Context, patch ...repo.PatchChange) error {
	return a.ChangeRepo.PatchChange(ctx, a.OriginChange, patch...)
}
