package oidc

import (
	"context"
	"testing"
	"time"

	"gitea.dcglab.co.uk/steve/restic-manager/internal/server/config"
	"gitea.dcglab.co.uk/steve/restic-manager/internal/server/oidc/oidctest"
)

func TestClientExchangeAgainstStub(t *testing.T) {
	t.Parallel()
	stub := oidctest.New(t)
	cfg := &config.OIDCConfig{
		Issuer: stub.URL(), ClientID: "test-client", ClientSecret: "x",
		Scopes: []string{"openid"}, RoleClaim: "groups",
		RoleMapping: map[string]string{"rm-admins": "admin"},
	}
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	c, err := New(ctx, cfg, "http://rm.example")
	if err != nil {
		t.Fatalf("new client: %v", err)
	}
	code := stub.MintCode(map[string]any{
		"sub":                "abc",
		"preferred_username": "alice",
		"email":              "alice@example.com",
		"groups":             []string{"rm-admins"},
	})
	verifier, _, err := PKCEPair()
	if err != nil {
		t.Fatalf("pkce: %v", err)
	}
	claims, raw, err := c.Exchange(ctx, code, verifier)
	if err != nil {
		t.Fatalf("exchange: %v", err)
	}
	if claims.Subject != "abc" || claims.PreferredUsername != "alice" {
		t.Errorf("claims: %+v", claims)
	}
	if c.MapRole(claims.Roles) != "admin" {
		t.Errorf("role: got %q", c.MapRole(claims.Roles))
	}
	if raw == "" {
		t.Error("raw id_token must be non-empty")
	}
}
