package utils

import (
	"baron-sso-backend/internal/domain"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestValidatePasswordWithPolicy(t *testing.T) {
	policy := &domain.PasswordPolicy{
		MinLength:         8,
		Lowercase:         true,
		Uppercase:         true,
		Number:            true,
		NonAlphanumeric:   true,
		MinCharacterTypes: 3,
	}

	t.Run("Valid Password", func(t *testing.T) {
		err := ValidatePasswordWithPolicy(policy, "Pass1234!")
		assert.NoError(t, err)
	})

	t.Run("Too Short", func(t *testing.T) {
		err := ValidatePasswordWithPolicy(policy, "P123!")
		assert.Error(t, err)
		assert.Contains(t, err.Error(), "최소 8자")
	})

	t.Run("Missing Lowercase", func(t *testing.T) {
		err := ValidatePasswordWithPolicy(policy, "PASS1234!")
		assert.Error(t, err)
		assert.Contains(t, err.Error(), "소문자")
	})

	t.Run("Missing Symbol", func(t *testing.T) {
		err := ValidatePasswordWithPolicy(policy, "Pass1234")
		assert.Error(t, err)
		assert.Contains(t, err.Error(), "특수문자")
	})
}

func TestGeneratePasswordWithPolicy(t *testing.T) {
	policy := &domain.PasswordPolicy{
		MinLength:       16,
		Lowercase:       true,
		Uppercase:       true,
		Number:          true,
		NonAlphanumeric: true,
	}

	t.Run("Generate and Validate", func(t *testing.T) {
		password, err := GeneratePasswordWithPolicy(policy)
		assert.NoError(t, err)
		assert.Len(t, password, 16)

		// Generated password must satisfy the policy
		err = ValidatePasswordWithPolicy(policy, password)
		assert.NoError(t, err, "Generated password '%s' does not satisfy policy", password)
	})
}
