package middleware

import (
	"context"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"

	"github.com/sundynix/sundynix-gateway/internal/store"
)

type fakeSpaceRole struct{ role string }

func (f fakeSpaceRole) SpaceMemberRole(context.Context, string, string) string { return f.role }

func spaceGateEngine(uid, space, memberRole, minRole string) *gin.Engine {
	gin.SetMode(gin.TestMode)
	r := gin.New()
	r.Use(func(c *gin.Context) {
		if uid != "" {
			c.Set(CtxUserID, uid)
		}
		if space != "" {
			c.Set(CtxSpaceID, space)
		}
		c.Next()
	})
	r.POST("/agents", RequireSpaceRole(fakeSpaceRole{role: memberRole}, minRole),
		func(c *gin.Context) { c.String(http.StatusOK, "saved") })
	return r
}

func TestRequireSpaceRole_Gate(t *testing.T) {
	cases := []struct {
		name       string
		uid        string
		space      string
		memberRole string
		wantCode   int
	}{
		{"owner 放行", "u1", "s1", store.RoleOwner, http.StatusOK},
		{"admin 放行", "u1", "s1", store.RoleAdmin, http.StatusOK},
		{"member 放行", "u1", "s1", store.RoleMember, http.StatusOK},
		{"viewer 拦下(空间只读)", "u1", "s1", store.RoleViewer, http.StatusForbidden},
		{"非空间成员 拦下", "u1", "s1", "", http.StatusForbidden},
		{"未登录 401", "", "s1", store.RoleOwner, http.StatusUnauthorized},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			r := spaceGateEngine(tc.uid, tc.space, tc.memberRole, store.RoleMember)
			w := httptest.NewRecorder()
			r.ServeHTTP(w, httptest.NewRequest(http.MethodPost, "/agents", nil))
			if w.Code != tc.wantCode {
				t.Errorf("状态码=%d, 期望 %d（body=%s）", w.Code, tc.wantCode, w.Body.String())
			}
		})
	}
}
