namespace ZB.MOM.WW.ScadaBridge.NotificationService.Ews;
///
/// One-shot EWS mail submission (CreateItem, SendOnly, BCC-only).
///
/// The seam the central Notification Outbox's EmailNotificationDeliveryAdapter calls when a
/// SmtpConfiguration selects the EWS transport, mirroring the role
/// ISmtpClientWrapper plays for the SMTP transport.
///
///
public interface IEwsMailSender
{
///
/// Sends one message through Exchange Web Services.
///
/// The endpoint, credential, sender, recipients and content to submit.
/// Token cancelling the send; propagates unwrapped when the caller cancels.
/// A task completing when Exchange has accepted the message.
///
/// The send failed for a reason retrying cannot fix — authentication (401/403), a wrong URL
/// (404), a schema fault, or a recipient rejection.
///
///
/// The send failed for an availability-shaped reason — network/DNS/timeout, HTTP 5xx/408/429,
/// or an ErrorServerBusy-class response code — and is worth retrying.
///
Task SendAsync(EwsSendRequest request, CancellationToken cancellationToken = default);
}
///
/// Everything one EWS submission needs. Carried per call rather than held on the sender so the
/// sender stays a stateless singleton and the credential never outlives the request.
///
/// The absolute HTTPS EWS URL (for example https://host/EWS/Exchange.asmx).
/// The service account, which may be domain-qualified (domain\user).
/// The service account password.
/// The sending mailbox address.
/// The recipients; all addressed BCC so they cannot see one another.
/// The message subject.
/// The plain-text message body.
///
/// The per-request timeout; a non-positive value leaves the default in force.
///
public sealed record EwsSendRequest(
Uri Endpoint,
string Username,
string Password,
string FromAddress,
IReadOnlyList BccRecipients,
string Subject,
string Body,
int TimeoutSeconds);
///
/// Signals an availability-shaped EWS failure that is worth retrying.
///
public class EwsTransientException : Exception
{
///
/// Initializes the exception with a message and optional inner exception.
///
/// Message describing the transient EWS failure; never carries the credential.
/// Optional underlying transport exception.
public EwsTransientException(string message, Exception? innerException = null)
: base(message, innerException) { }
}
///
/// Signals an EWS failure that retrying cannot fix, so the notification parks immediately.
///
public class EwsPermanentException : Exception
{
///
/// Initializes the exception with a message and optional inner exception.
///
/// Message describing the permanent EWS failure; never carries the credential.
/// Optional underlying transport exception.
public EwsPermanentException(string message, Exception? innerException = null)
: base(message, innerException) { }
}