package com.zb.mom.ww.mxgateway.client;

/**
 * Helpers for redacting secrets such as gateway API keys from log output.
 *
 * <p>API keys must never reach logs in plaintext. The methods on this class
 * produce shortened, masked forms safe for diagnostic messages.
 */
public final class MxGatewaySecrets {
    private MxGatewaySecrets() {
    }

    /**
     * Redacts the body of an API key, leaving only short prefix and suffix
     * windows so it remains comparable in logs.
     *
     * @param apiKey the API key to redact, may be {@code null} or empty
     * @return an empty string for {@code null}/empty input, {@code "<redacted>"}
     *         for keys eight characters or shorter, or a masked form preserving
     *         the leading and trailing four characters
     */
    public static String redactApiKey(String apiKey) {
        if (apiKey == null || apiKey.isEmpty()) {
            return "";
        }
        if (apiKey.length() <= 8) {
            return "<redacted>";
        }

        return apiKey.substring(0, 4)
                + "*".repeat(apiKey.length() - 8)
                + apiKey.substring(apiKey.length() - 4);
    }

    /**
     * Replaces gateway-style credential tokens (the {@code mxgw_} prefix and
     * any {@code Bearer} marker) inside a free-form string with a redaction
     * placeholder.
     *
     * @param value the string to scrub, may be {@code null}
     * @return an empty string for {@code null}, the original value when blank,
     *         or the value with credential tokens replaced by {@code "<redacted>"}
     */
    public static String redactCredentials(String value) {
        if (value == null || value.isBlank()) {
            return value == null ? "" : value;
        }

        String[] parts = value.split("\\s+");
        for (int index = 0; index < parts.length; index++) {
            if (parts[index].startsWith("mxgw_") || parts[index].equalsIgnoreCase("bearer")) {
                parts[index] = "<redacted>";
            }
        }
        return String.join(" ", parts);
    }

    /**
     * Replaces every occurrence of each supplied secret with the redaction
     * marker {@code "<redacted>"}. Unlike {@link #redactCredentials(String)},
     * which scrubs by pattern, this performs an exact-substring scrub of the
     * caller-known secrets — used to strip a credential the gateway echoed back
     * into a free-form failure message.
     *
     * @param message the message to scrub, may be {@code null}
     * @param secrets the exact secret substrings to remove; {@code null}, empty,
     *     and blank (whitespace-only) entries and a {@code null} array are ignored
     * @return {@code message} unchanged when it is {@code null} or no non-blank
     *     secret is supplied, otherwise the message with every secret occurrence
     *     replaced by {@code "<redacted>"}
     */
    public static String redactExact(String message, String... secrets) {
        if (message == null || secrets == null) {
            return message;
        }

        String result = message;
        for (String secret : secrets) {
            if (secret == null || secret.isBlank()) {
                // A blank "secret" would over-redact real whitespace; skip it.
                continue;
            }
            result = result.replace(secret, "<redacted>");
        }
        return result;
    }
}
