namespace ScadaLink.NotificationService;

/// <summary>
/// NS-009: Scrubs SMTP credential secrets out of free text (typically exception
/// messages echoed back by an SMTP server) before that text is written to a log.
/// MailKit authentication exceptions can contain server responses that quote the
/// supplied credentials; this prevents a password, client secret, or OAuth2 token
/// from leaking into the operational logs.
/// </summary>
internal static class CredentialRedactor
{
    private const string Mask = "***REDACTED***";

    /// <summary>
    /// Returns <paramref name="text"/> with every secret component of the supplied
    /// colon-delimited credential string masked.
    /// </summary>
    /// <param name="text">The text to scrub (e.g. an exception message).</param>
    /// <param name="credentials">
    /// The credential string in use — Basic Auth <c>user:pass</c> or OAuth2
    /// <c>tenantId:clientId:clientSecret</c>. May be null.
    /// </param>
    public static string Scrub(string? text, string? credentials)
    {
        if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(credentials))
        {
            return text ?? string.Empty;
        }

        var result = text;

        // Mask each individual colon-delimited component (covers user, password,
        // tenant, clientId, clientSecret) and the whole packed string. Order longest
        // first so a component that is a substring of another is still fully masked.
        var parts = credentials.Split(':')
            .Where(p => p.Length >= 4)
            .Append(credentials)
            .Distinct()
            .OrderByDescending(p => p.Length);

        foreach (var part in parts)
        {
            result = result.Replace(part, Mask, StringComparison.Ordinal);
        }

        return result;
    }
}
