<?php
/**
 * Privacy-safe mail error normalization.
 *
 * @package SubmissionInbox
 */

namespace SUBIN\MailLog;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Removes credentials and bearer material before errors enter durable storage.
 */
final class MailErrorSanitizer {
	/**
	 * @param mixed             $message Raw error.
	 * @param array<int,string> $known_secrets Configured values which must never be logged.
	 * @param int               $limit Maximum stored characters.
	 * @return string
	 */
	public static function sanitize( $message, array $known_secrets = array(), $limit = 500 ) {
		$message = wp_strip_all_tags( (string) $message );
		foreach ( $known_secrets as $secret ) {
			$secret = (string) $secret;
			if ( '' !== $secret ) {
				$message = str_replace( $secret, '[redacted]', $message );
			}
		}

		$patterns = array(
			'/\b(Basic|Bearer)\s+[A-Za-z0-9._~+\/=:-]+/i',
			'/\b(username)\s*[:=]\s*([^\s,;]+)\s+(password|passwd|pwd)\s*[:=]\s*([^\s,;]+)/i',
			'/\b(password|passwd|pwd|secret|api[_-]?key|access[_-]?token|refresh[_-]?token|token|authorization)\s*[:=]\s*([^\s,;]+)/i',
		);
		foreach ( $patterns as $pattern ) {
			$message = preg_replace_callback(
				$pattern,
				static function ( array $matches ) {
					if ( isset( $matches[3] ) ) {
						return $matches[1] . '=[redacted] ' . $matches[3] . '=[redacted]';
					}
					if ( isset( $matches[1] ) && in_array( strtolower( $matches[1] ), array( 'basic', 'bearer' ), true ) ) {
						return $matches[1] . ' [redacted]';
					}

					return $matches[1] . '=[redacted]';
				},
				(string) $message
			);
		}

		$message = trim( (string) preg_replace( '/\s+/', ' ', (string) $message ) );
		$message = sanitize_textarea_field( $message );
		$limit   = max( 1, absint( $limit ) );

		return function_exists( 'mb_substr' ) ? mb_substr( $message, 0, $limit ) : substr( $message, 0, $limit );
	}
}
