package middleware_test

import (
	"context"
	"testing"

	"github.com/jfraeys/fetch_ml/internal/auth"
	"github.com/jfraeys/fetch_ml/internal/middleware"
)

func TestPrivacyEnforcer_CanAccess(t *testing.T) {
	ctx := context.Background()

	tests := []struct {
		name         string
		user         *auth.User
		owner        string
		level        string
		team         string
		enforceTeams bool
		want         bool
	}{
		{
			name:  "owner can access private",
			user:  &auth.User{Name: "alice"},
			owner: "alice",
			level: "private",
			want:  true,
		},
		{
			name:  "non-owner cannot access private",
			user:  &auth.User{Name: "bob"},
			owner: "alice",
			level: "private",
			want:  false,
		},
		{
			name:  "admin can access private",
			user:  &auth.User{Name: "admin", Admin: true},
			owner: "alice",
			level: "private",
			want:  true,
		},
		{
			name:  "public allows all",
			user:  &auth.User{Name: "anyone"},
			owner: "alice",
			level: "public",
			want:  true,
		},
		{
			name:  "owner can access team",
			user:  &auth.User{Name: "alice"},
			owner: "alice",
			level: "team",
			team:  "research",
			want:  true,
		},
		{
			name:         "non-owner denied team when enforcing",
			user:         &auth.User{Name: "bob"},
			owner:        "alice",
			level:        "team",
			team:         "research",
			enforceTeams: true,
			want:         false,
		},
		{
			name:         "non-owner allowed team when not enforcing",
			user:         &auth.User{Name: "bob"},
			owner:        "alice",
			level:        "team",
			team:         "research",
			enforceTeams: false,
			want:         true,
		},
		{
			name:  "anonymized allows all",
			user:  &auth.User{Name: "anyone"},
			owner: "alice",
			level: "anonymized",
			want:  true,
		},
		{
			name:  "unknown level defaults to private (deny)",
			user:  &auth.User{Name: "bob"},
			owner: "alice",
			level: "unknown",
			want:  false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			pe := middleware.NewPrivacyEnforcer(tt.enforceTeams, false)
			got, err := pe.CanAccess(ctx, tt.user, tt.owner, tt.level, tt.team)
			if err != nil {
				t.Errorf("CanAccess() error = %v", err)
				return
			}
			if got != tt.want {
				t.Errorf("CanAccess() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestGetPrivacyLevelFromString(t *testing.T) {
	tests := []struct {
		input    string
		expected middleware.PrivacyLevel
	}{
		{"private", middleware.PrivacyPrivate},
		{"team", middleware.PrivacyTeam},
		{"public", middleware.PrivacyPublic},
		{"anonymized", middleware.PrivacyAnonymized},
		{"unknown", middleware.PrivacyPrivate}, // Default
		{"", middleware.PrivacyPrivate},        // Default
	}

	for _, tt := range tests {
		t.Run(tt.input, func(t *testing.T) {
			got := middleware.GetPrivacyLevelFromString(tt.input)
			if got != tt.expected {
				t.Errorf("GetPrivacyLevelFromString(%q) = %v, want %v",
					tt.input, got, tt.expected)
			}
		})
	}
}
