package httpapi

import (
	"testing"
	"time"

	"github.com/go-jose/go-jose/v4"
	"github.com/go-jose/go-jose/v4/jwt"
)

// extractIdentity pulls the display identity plus the thin-account fields
// (match_key from the configured claim, roles from groups) out of an id_token.
// It does not verify the signature, so a throwaway HS256 key suffices here.
func TestExtractIdentity(t *testing.T) {
	key := []byte("any-throwaway-signing-key-32-bytes!!")
	sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: key}, (&jose.SignerOptions{}).WithType("JWT"))
	if err != nil {
		t.Fatalf("signer: %v", err)
	}
	tok, err := jwt.Signed(sig).
		Claims(jwt.Claims{Subject: "sub-123", Expiry: jwt.NewNumericDate(time.Now().Add(time.Hour))}).
		Claims(map[string]any{
			"preferred_username": "alice",
			"email":              "alice@example.net",
			"avatar":             "https://a/av.png",
			"groups":             []any{"admins", "staff"},
		}).Serialize()
	if err != nil {
		t.Fatalf("sign: %v", err)
	}

	id, err := extractIdentity(tok, "", "email")
	if err != nil {
		t.Fatalf("extract: %v", err)
	}
	if id.User.ID != "sub-123" || id.User.Name != "alice" || id.User.Avatar != "https://a/av.png" {
		t.Errorf("user wrong: %+v", id.User)
	}
	if id.MatchKey != "alice@example.net" {
		t.Errorf("match_key: got %q, want alice@example.net", id.MatchKey)
	}
	if len(id.Roles) != 2 || id.Roles[0] != "admins" || id.Roles[1] != "staff" {
		t.Errorf("roles: got %v, want [admins staff]", id.Roles)
	}

	// No name claim → falls back to sub; absent match claim → empty (never matches).
	tok2, _ := jwt.Signed(sig).
		Claims(jwt.Claims{Subject: "sub-x", Expiry: jwt.NewNumericDate(time.Now().Add(time.Hour))}).
		Serialize()
	id2, err := extractIdentity(tok2, "", "email")
	if err != nil {
		t.Fatalf("extract2: %v", err)
	}
	if id2.User.Name != "sub-x" || id2.MatchKey != "" || len(id2.Roles) != 0 {
		t.Errorf("fallback wrong: %+v", id2)
	}
}
