package globalapi

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

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/observability/pkg/common/constants"
	"github.com/tidbcloud/observability/pkg/common/errors"
	"github.com/tidbcloud/observability/pkg/common/message"
	"github.com/tidbcloud/observability/pkg/common/structs"
)

func TestQueryRegionRoutes_LogicalRegionRequiresRegionID(t *testing.T) {
	t.Run("logical region without region_id returns 400", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Request, _ = http.NewRequest("GET", "/api/v1/routes", nil)

		// X-Logical-Region set, but Vendor/Region empty (no X-Region-Id provided)
		reqParams := structs.RequestParameters{
			CommonReqInfo: structs.CommonReqInfo{
				Vendor: "",
				Region: "",
			},
			Headers: map[string]string{
				string(constants.OpenAPIHeaderLogicalRegion): "us-west-2-primary",
			},
		}
		c.Set(structs.GlobalServerRequestParametersKey, reqParams)

		QueryRegionRoutes(c)

		assert.Equal(t, http.StatusBadRequest, w.Code)

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

		result := &message.Result{}
		assert.NoError(t, json.Unmarshal(data, result))
		assert.Equal(t, int(errors.ParameterInvalid), result.Code)
		assert.Contains(t, result.Message, "X-Region-Id")
	})

	t.Run("logical region with valid region_id proceeds past validation", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Request, _ = http.NewRequest("GET", "/api/v1/routes", nil)

		// X-Logical-Region set, Vendor+Region populated from X-Region-Id
		reqParams := structs.RequestParameters{
			CommonReqInfo: structs.CommonReqInfo{
				Vendor: "aws",
				Region: "us-west-2",
			},
			Headers: map[string]string{
				string(constants.OpenAPIHeaderLogicalRegion): "us-west-2-primary",
				string(constants.OpenAPIHeaderRegionID):      "aws-us-west-2",
			},
		}
		c.Set(structs.GlobalServerRequestParametersKey, reqParams)

		QueryRegionRoutes(c)

		// Validation passes; it may succeed (200) or fail downstream (500) depending on test setup.
		// What matters is it is NOT a 400 from the new validation.
		assert.NotEqual(t, http.StatusBadRequest, w.Code)
	})

	t.Run("no logical region does not require region_id check", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Request, _ = http.NewRequest("GET", "/api/v1/routes", nil)

		// No X-Logical-Region header — existing path, no new validation triggered
		reqParams := structs.RequestParameters{
			CommonReqInfo: structs.CommonReqInfo{
				Vendor: "aws",
				Region: "us-west-2",
			},
			Headers: map[string]string{
				string(constants.OpenAPIHeaderRegionID): "aws-us-west-2",
			},
		}
		c.Set(structs.GlobalServerRequestParametersKey, reqParams)

		QueryRegionRoutes(c)

		assert.NotEqual(t, http.StatusBadRequest, w.Code)
	})
}
