package mgmthttpcli

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

	"github.com/go-resty/resty/v2"
	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
)

var _ = Describe("NextGen Client", func() {
	var (
		server *httptest.Server
		client NextGenAPI
	)

	AfterEach(func() {
		if server != nil {
			server.Close()
		}
	})

	Describe("SetTiProxyExternalDNS", func() {
		var (
			receivedMethod string
			receivedPath   string
			receivedBody   []byte
			clusterID      = "test-cluster-123"
			tidbGroupID    = "test-tidb-group-456"
			expectedPath   = "/proxy/nextgen/clusters/test-cluster-123/api/premium/v1/clusters/test-cluster-123/tidbGroups/test-tidb-group-456/tiproxy/externalDNS:set"
		)

		BeforeEach(func() {
			server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				receivedMethod = r.Method
				receivedPath = r.URL.Path
				receivedBody, _ = io.ReadAll(r.Body)
				w.WriteHeader(http.StatusOK)
				w.Write([]byte(`{}`))
			}))

			restyClient := resty.New().SetBaseURL(server.URL)
			client = &nextgen{core: restyClient}
		})

		Context("when TTL is provided", func() {
			It("should send POST request to correct path with enable and ttl in body", func() {
				ttl := int32(300)
				request := &SetTiProxyExternalDNSRequest{
					Enable: true,
					TTL:    &ttl,
				}

				err := client.SetTiProxyExternalDNS(context.Background(), clusterID, tidbGroupID, request)

				Expect(err).To(BeNil())
				Expect(receivedMethod).To(Equal("POST"))
				Expect(receivedPath).To(Equal(expectedPath))

				var body map[string]interface{}
				err = json.Unmarshal(receivedBody, &body)
				Expect(err).To(BeNil())
				Expect(body["enable"]).To(Equal(true))
				Expect(body["ttl"]).To(Equal(float64(300)))
			})
		})

		Context("when TTL is nil", func() {
			It("should send POST request with enable but omit ttl from body", func() {
				request := &SetTiProxyExternalDNSRequest{
					Enable: true,
					TTL:    nil,
				}

				err := client.SetTiProxyExternalDNS(context.Background(), clusterID, tidbGroupID, request)

				Expect(err).To(BeNil())
				Expect(receivedMethod).To(Equal("POST"))
				Expect(receivedPath).To(Equal(expectedPath))

				var body map[string]interface{}
				err = json.Unmarshal(receivedBody, &body)
				Expect(err).To(BeNil())
				Expect(body["enable"]).To(Equal(true))
				Expect(body).NotTo(HaveKey("ttl"))
			})
		})

		Context("when enable is false with TTL", func() {
			It("should send POST request with enable false and ttl", func() {
				ttl := int32(600)
				request := &SetTiProxyExternalDNSRequest{
					Enable: false,
					TTL:    &ttl,
				}

				err := client.SetTiProxyExternalDNS(context.Background(), clusterID, tidbGroupID, request)

				Expect(err).To(BeNil())
				Expect(receivedMethod).To(Equal("POST"))
				Expect(receivedPath).To(Equal(expectedPath))

				var body map[string]interface{}
				err = json.Unmarshal(receivedBody, &body)
				Expect(err).To(BeNil())
				Expect(body["enable"]).To(Equal(false))
				Expect(body["ttl"]).To(Equal(float64(600)))
			})
		})
	})
})
