package system

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

	"github.com/gin-gonic/gin"
	"github.com/pingcap-inc/nexuscrm-api-host/dialect"
)

func TestVersionsForUsesMountedDialectVersionsOnly(t *testing.T) {
	gin.SetMode(gin.TestMode)
	c, w := newSystemTestContext(http.MethodGet, "/services/data")

	NewSystemHandler().VersionsFor([]dialect.Mount{
		{Dialect: "toy-neutral", BasePath: "/services/data", Version: "toy1", Path: "/services/data/toy1"},
	})(c)

	body := decodeSystemJSON[[]map[string]any](t, w)
	if len(body) != 1 || body[0]["version"] != "toy1" || body[0]["url"] != "/services/data/toy1" {
		t.Fatalf("versions body = %#v", body)
	}
}

// TestVersionsForUsesAuthoritativeMountPath guards the #1715 regression the Codex
// gate caught: the discovery url must come from the Mount's authoritative Path,
// not a reconstruction that assumes the /services/data root. A dialect mounted at
// another BasePath must advertise its real, live location — never a dead
// /services/data URL.
func TestVersionsForUsesAuthoritativeMountPath(t *testing.T) {
	gin.SetMode(gin.TestMode)
	c, w := newSystemTestContext(http.MethodGet, "/services/data")

	NewSystemHandler().VersionsFor([]dialect.Mount{
		{Dialect: "ext", BasePath: "/toy-ext", Version: "ext1", Path: "/toy-ext/ext1"},
	})(c)

	body := decodeSystemJSON[[]map[string]any](t, w)
	if len(body) != 1 || body[0]["url"] != "/toy-ext/ext1" || body[0]["version"] != "ext1" {
		t.Fatalf("version row = %#v, want authoritative url /toy-ext/ext1 (not a /services/data reconstruction)", body)
	}
}

func newSystemTestContext(method, target string) (*gin.Context, *httptest.ResponseRecorder) {
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request = httptest.NewRequest(method, target, nil)
	return c, w
}

func decodeSystemJSON[T any](t *testing.T, w *httptest.ResponseRecorder) T {
	t.Helper()
	if w.Code != http.StatusOK {
		t.Fatalf("status = %d, want 200; body=%s", w.Code, w.Body.String())
	}
	var body T
	if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil {
		t.Fatalf("unmarshal response body: %v body=%s", err, w.Body.String())
	}
	return body
}
