package cloudconfig

import (
	"bytes"
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"

	"github.com/gin-gonic/gin"
	ccapi "github.com/tidbcloud/devops/api/cloudconfig"
	"github.com/tidbcloud/devops/pkg/infra/consts"
	"github.com/tidbcloud/devops/pkg/infra/utils/pointer"
	opsvc "github.com/tidbcloud/devops/pkg/service/operation"
	"go.uber.org/mock/gomock"

	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
)

var _ = Describe("[UpdateComponentImage]", func() {
	DescribeTable("resolves the operation applicant",
		func(author, expectedApplicant string) {
			gin.SetMode(gin.TestMode)
			mockController := gomock.NewController(GinkgoT())
			operationService := opsvc.NewMockOperationServiceAPI(mockController)
			controller := &CloudConfigController{opSvc: operationService}

			operationService.EXPECT().
				CreateInstance(gomock.Any(), gomock.Any()).
				DoAndReturn(func(_ context.Context, param opsvc.CreateInstanceParam) (*uint64, error) {
					Expect(param.Applicant).To(Equal(expectedApplicant))
					return pointer.Pointer(uint64(42)), nil
				})

			body, err := json.Marshal(&ccapi.UpdateComponentImageReq{
				ClusterType: "SHARED_POOL",
				Version:     "v8.5.4",
				BaseImage:   "us.gcr.io/pingcap-public/tidbx/tikv",
				Tag:         "v8.5.4-nextgen.202510.31",
				Policy:      "immediate",
				Author:      author,
			})
			Expect(err).NotTo(HaveOccurred())

			router := gin.New()
			router.POST("/cloudconfig/versions/component/:component", func(ctx *gin.Context) {
				ctx.Set(consts.CtxUserEmail, "api-key-owner@pingcap.com")
				controller.UpdateComponentImage(ctx)
			})

			recorder := httptest.NewRecorder()
			request := httptest.NewRequest(http.MethodPost, "/cloudconfig/versions/component/tikv", bytes.NewReader(body))
			request.Header.Set("Content-Type", "application/json")
			router.ServeHTTP(recorder, request)

			Expect(recorder.Code).To(Equal(http.StatusOK))
		},
		Entry("uses the request author when provided", "release-applicant@pingcap.com", "release-applicant@pingcap.com"),
		Entry("falls back to the authenticated API key owner", "", "api-key-owner@pingcap.com"),
	)
})
