package auth

import (
	"errors"
	"testing"
	"time"

	"github.com/wormhole/wormhole/internal/config"
)

func TestLoginLimiterBlocksAfterMaxAttempts(t *testing.T) {
	l := NewLoginLimiter(&config.AuthConfig{
		LoginMaxAttempts: 3,
		LoginWindow:      time.Minute,
		LoginLockout:     10 * time.Minute,
	})

	ip := "192.168.1.1"
	user := "admin"

	for i := 0; i < 3; i++ {
		if _, blocked := l.IsBlocked(ip, user); blocked {
			t.Fatalf("unexpected block at attempt %d", i+1)
		}
		l.RecordFailure(ip, user)
	}

	retry, blocked := l.IsBlocked(ip, user)
	if !blocked || retry <= 0 {
		t.Fatalf("expected block after max attempts, retry=%v blocked=%v", retry, blocked)
	}
}

func TestLoginLimiterResetClearsBlock(t *testing.T) {
	l := NewLoginLimiter(&config.AuthConfig{
		LoginMaxAttempts: 2,
		LoginWindow:      time.Minute,
		LoginLockout:     time.Minute,
	})

	ip := "10.0.0.1"
	l.RecordFailure(ip, "u1")
	l.RecordFailure(ip, "u1")
	if _, blocked := l.IsBlocked(ip, "u1"); !blocked {
		t.Fatal("expected blocked")
	}

	l.Reset(ip, "u1")
	if _, blocked := l.IsBlocked(ip, "u1"); blocked {
		t.Fatal("expected unblocked after reset")
	}
}

func TestLoginBlockedError(t *testing.T) {
	err := &LoginBlockedError{RetryAfter: 30 * time.Second}
	if !errors.As(err, new(*LoginBlockedError)) {
		t.Fatal("LoginBlockedError should be detectable via errors.As")
	}
}
