package middleware

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

	"github.com/ultisuite/ulti-backend/internal/apitokens"
	"github.com/ultisuite/ulti-backend/internal/auth"
)

func TestEnforceApiTokenPolicyAllowsMailRead(t *testing.T) {
	authCtx := &apitokens.AuthContext{
		ExternalID: "user-1",
		Permissions: []apitokens.PermissionGrant{
			{Resource: "mail.messages", Read: true},
		},
		MailScope:  apitokens.MailScope{AllAccounts: true},
		DriveScope: apitokens.DriveScope{AllFolders: true},
	}
	called := false
	handler := EnforceApiTokenPolicy()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		called = true
		w.WriteHeader(http.StatusOK)
	}))

	req := httptest.NewRequest(http.MethodGet, "/api/v1/mail/messages", nil)
	ctx := context.WithValue(context.Background(), claimsKey, &auth.Claims{Sub: "user-1"})
	ctx = context.WithValue(ctx, apiTokenKey, authCtx)
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req.WithContext(ctx))

	if rec.Code != http.StatusOK || !called {
		t.Fatalf("status=%d called=%v", rec.Code, called)
	}
}

func TestEnforceApiTokenPolicyDeniesMissingPermission(t *testing.T) {
	authCtx := &apitokens.AuthContext{
		ExternalID: "user-1",
		Permissions: []apitokens.PermissionGrant{
			{Resource: "mail.messages", Read: true},
		},
		MailScope:  apitokens.MailScope{AllAccounts: true},
		DriveScope: apitokens.DriveScope{AllFolders: true},
	}
	handler := EnforceApiTokenPolicy()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		t.Fatal("handler should not run")
	}))

	req := httptest.NewRequest(http.MethodPost, "/api/v1/mail/send", nil)
	ctx := context.WithValue(context.Background(), claimsKey, &auth.Claims{Sub: "user-1"})
	ctx = context.WithValue(ctx, apiTokenKey, authCtx)
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req.WithContext(ctx))

	if rec.Code != http.StatusForbidden {
		t.Fatalf("status=%d", rec.Code)
	}
}
