package globalapi

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

	"github.com/tidbcloud/observability/pkg/common/interceptor"

	"github.com/tidbcloud/observability/pkg/common/constants"

	"github.com/tidbcloud/observability/pkg/common/errors"
	"github.com/tidbcloud/observability/pkg/common/message"

	"github.com/gin-gonic/gin"

	"github.com/stretchr/testify/assert"
)

func TestRecover(t *testing.T) {
	testRecover := testEngine.Group("/recover")
	testRecover.Use(gin.CustomRecovery(interceptor.Recover))

	testRecover.GET("/panic/", func(context *gin.Context) {
		panic("something wrong")
	})

	testRecover.GET("/ok/", ServiceInfo)

	t.Run("panic", func(t *testing.T) {

		w := httptest.NewRecorder()

		req, _ := http.NewRequest("GET", "/recover/panic/", nil)

		testEngine.ServeHTTP(w, req)
		assert.Equal(t, http.StatusInternalServerError, w.Code)

		res := w.Result()
		defer res.Body.Close()

		data, err := io.ReadAll(res.Body)
		assert.NoError(t, err)

		result := &message.Result{}
		err = json.Unmarshal(data, result)
		assert.NoError(t, err)

		assert.Equal(t, int(errors.UnrecognizedError), result.Code)
		assert.Equal(t, "something wrong", result.Message)
	})
	t.Run("no panic", func(t *testing.T) {
		w := httptest.NewRecorder()

		req, _ := http.NewRequest("GET", "/recover/ok/", nil)
		testEngine.ServeHTTP(w, req)
		assert.Equal(t, http.StatusOK, w.Code)

		res := w.Result()
		defer res.Body.Close()

		data, err := io.ReadAll(res.Body)
		assert.NoError(t, err)

		result := &message.Result{
			Data: &message.GetServiceInfoResp{},
		}
		err = json.Unmarshal(data, result)
		assert.NoError(t, err)

		assert.Equal(t, errors.SUCCESS, result.Code)
		assert.Equal(t, constants.ObservabilityGlobalServer, result.Data.(*message.GetServiceInfoResp).ServiceName)
	})
}

func TestByocObservabilityVcpuRouteRegistered(t *testing.T) {
	found := false
	for _, route := range testEngine.Routes() {
		if route.Method == http.MethodGet && route.Path == "/api/v1/external/:bizType/orgs/:tenantID/byocVcpuPools/observabilityVcpu" {
			found = true
			break
		}
	}
	assert.True(t, found, "byoc observability vcpu route should be registered")
}
