package middleware

import (
	"context"
	"errors"
	"testing"
)

func TestContextWithAuthRoundTrip(t *testing.T) {
	ctx := ContextWithAuth(context.Background(), "0xabc", 4, true)

	if got := UserAddress(ctx); got != "0xabc" {
		t.Fatalf("UserAddress() = %q, want %q", got, "0xabc")
	}
	if got := UserTrack(ctx); got != 4 {
		t.Fatalf("UserTrack() = %d, want 4", got)
	}
	if !IsAuthenticated(ctx) {
		t.Fatal("IsAuthenticated() = false, want true")
	}
}

func TestUserTrackDefaultsToTrack1OnBareContext(t *testing.T) {
	if got := UserTrack(context.Background()); got != defaultTrackLevel {
		t.Fatalf("UserTrack(empty) = %d, want %d", got, defaultTrackLevel)
	}
}

func TestUserAddressEmptyOnBareContext(t *testing.T) {
	if got := UserAddress(context.Background()); got != "" {
		t.Fatalf("UserAddress(empty) = %q, want empty", got)
	}
}

func TestIsAuthenticatedFalseOnBareContext(t *testing.T) {
	if IsAuthenticated(context.Background()) {
		t.Fatal("IsAuthenticated(empty) = true, want false")
	}
}

// TestContextKeyIsolation proves that the typed ctxKey values cannot be
// shadowed by a caller using bare-string keys with the same spelling.
// This is the specific class of bug fixed by this PR.
func TestContextKeyIsolation(t *testing.T) {
	ctx := context.WithValue(context.Background(), "user_address", "injected")
	if got := UserAddress(ctx); got != "" {
		t.Fatalf("expected empty address (bare string key must not collide), got %q", got)
	}
}

func TestErrMissingAuthorizationIsSentinel(t *testing.T) {
	if ErrMissingAuthorization == nil {
		t.Fatal("ErrMissingAuthorization must not be nil")
	}
	wrapped := errors.New("wrapped: " + ErrMissingAuthorization.Error())
	if errors.Is(wrapped, ErrMissingAuthorization) {
		t.Fatal("string-wrapped error must not satisfy errors.Is (smoke check)")
	}
	if !errors.Is(ErrMissingAuthorization, ErrMissingAuthorization) {
		t.Fatal("ErrMissingAuthorization must satisfy errors.Is against itself")
	}
}
