using System.Text.RegularExpressions;

namespace NexusShell.Services.Diagnostics;

public static partial class LogRedactor
{
    private static readonly string[] SensitiveKeys =
    [
        "password", "token", "secret", "apikey", "api_key", "authorization",
        "bearer", "credential", "privatekey", "private_key", "connectionstring", "connection_string",
        "userid", "user_id",
    ];

    [GeneratedRegex(@"(password|token|secret|apikey|api_key|authorization|bearer|user\s*id|userid)\s*[=:]\s*[^;\s]+", RegexOptions.IgnoreCase)]
    private static partial Regex InlineSecretPattern();

    [GeneratedRegex(@"(authorization\s*:\s*bearer)\s+[A-Za-z0-9._~+/=-]+", RegexOptions.IgnoreCase)]
    private static partial Regex BearerHeaderPattern();

    [GeneratedRegex(@"(eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)")]
    private static partial Regex JwtPattern();

    public static string Redact(string? value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return string.Empty;
        }

        var redacted = BearerHeaderPattern().Replace(value, "$1 [REDACTED]");
        redacted = InlineSecretPattern().Replace(redacted, "$1=[REDACTED]");
        redacted = JwtPattern().Replace(redacted, "[REDACTED_JWT]");
        return redacted;
    }

    public static IReadOnlyDictionary<string, string>? RedactProperties(
        IReadOnlyDictionary<string, string>? properties)
    {
        if (properties is null || properties.Count == 0)
        {
            return properties;
        }

        var result = new Dictionary<string, string>(properties.Count, StringComparer.OrdinalIgnoreCase);
        foreach (var (key, val) in properties)
        {
            if (SensitiveKeys.Any(s => key.Contains(s, StringComparison.OrdinalIgnoreCase)))
            {
                result[key] = "[REDACTED]";
            }
            else
            {
                result[key] = Redact(val);
            }
        }

        return result;
    }
}
