package logger

import (
	"regexp"
)

// DefaultRedactionPatterns contains built-in patterns for redacting sensitive data
// Each pattern should capture the key part in group 1 and the value will be replaced
var DefaultRedactionPatterns = []string{
	// Passwords in various formats - capture key, replace value
	`(password\s*=\s*)['"][^'"]*['"]`,
	`(password\s*:\s*)['"][^'"]*['"]`,
	// Connection strings - capture protocol://user:, replace password and @
	`(\w+://[^:@]+:)[^@]+(@)`,
	// Set password statements
	`(set\s+password\s+for[^=]*=\s*)['"][^'"]*['"]`,
	// Tokens and API keys
	`(token\s*=\s*)['"][^'"]*['"]`,
	`(api[_-]?key\s*=\s*)['"][^'"]*['"]`,
	`(secret\s*=\s*)['"][^'"]*['"]`,
	// Authorization headers
	`(authorization\s*:\s*)['"][^'"]*['"]`,
	`(bearer\s+)[A-Za-z0-9\._-]+`,
}

// Redactor handles query redaction for sensitive data
type Redactor struct {
	enabled  bool
	patterns []*regexp.Regexp
}

// NewRedactor creates a new redactor with optional custom patterns
func NewRedactor(enabled bool, customPatterns []string) *Redactor {
	if !enabled {
		return &Redactor{enabled: false}
	}

	// Combine default and custom patterns
	allPatterns := append([]string{}, DefaultRedactionPatterns...)
	allPatterns = append(allPatterns, customPatterns...)

	// Compile all patterns
	compiled := make([]*regexp.Regexp, 0, len(allPatterns))
	for _, pattern := range allPatterns {
		// Use (?i) for case-insensitive matching
		compiled = append(compiled, regexp.MustCompile("(?i)"+pattern))
	}

	return &Redactor{
		enabled:  true,
		patterns: compiled,
	}
}

// RedactQuery applies redaction patterns to a query string
func (r *Redactor) RedactQuery(query string) string {
	if !r.enabled {
		return query
	}

	redacted := query
	for _, pattern := range r.patterns {
		// For connection string pattern (two groups), preserve the @
		if pattern.String() == "(?i)(\\w+://[^:@]+:)[^@]+(@)" {
			redacted = pattern.ReplaceAllString(redacted, "${1}[REDACTED]${2}")
		} else {
			// For all other patterns (single group capturing key)
			redacted = pattern.ReplaceAllString(redacted, "${1}[REDACTED]")
		}
	}

	return redacted
}
