package connector_outboundintent

import (
	"context"
	"encoding/json"
	"errors"
	"sort"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"

	connector_mail "github.com/pingcap-inc/nexuscrm-connectors/features/connector/mail"
	connector_oauth "github.com/pingcap-inc/nexuscrm-connectors/features/connector/oauth"
	connector_throttle "github.com/pingcap-inc/nexuscrm-connectors/features/connector/throttle"
	commonv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/commonv1"
	outboundintentv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/outboundintentv1"
)

const (
	maxMailBindingValueBytes = 512
	maxMailScopeCount        = 64
	maxMailScopeBytes        = 4096
	mailCheckpointReserve    = time.Second
)

// MailBinding is the exact Catalog-owned destination selected for a mail
// intent. ConnectorKey selects a provider registered by the admitted
// Integration composition; credential values never cross this seam.
type MailBinding struct {
	ConnectorKey   string
	CredentialRef  string
	EndpointClass  string
	RequiredScopes []string
}

type MailAuthority interface {
	ResolveMail(context.Context, Command) (MailBinding, error)
}

// ResolvedMailBinding adds the secret-free throttle identity proven by an
// exact Catalog authority without changing the released MailBinding shape.
type ResolvedMailBinding struct {
	MailBinding
	Credential connector_throttle.ResolvedCredential
}

type ResolvedMailAuthority interface {
	ResolveResolvedMail(context.Context, Command) (ResolvedMailBinding, error)
	RevalidateResolvedMail(context.Context, ResolvedMailBinding) error
}

type MailOAuthResolver interface {
	Principal(context.Context, string, string) (*connector_oauth.ConnectedPrincipal, error)
	ResolveScopedAccessToken(context.Context, connector_oauth.ResolveScopedAccessTokenRequest) (string, error)
}

type MailProviderResolver interface {
	MailProvider(string) (connector_mail.Provider, bool)
}

type MailAttachmentReader interface {
	OpenOutboundMailAttachment(
		context.Context,
		outboundintentv1.OpenMailAttachmentRequest,
		outboundintentv1.MailAttachmentV1,
	) (outboundintentv1.OpenedMailAttachment, error)
}

type MailThrottler interface {
	Throttle(context.Context, string, string) (time.Duration, func(), error)
}

// ResolvedMailThrottler consumes only a credential identity already admitted
// by an exact Catalog authority. It is additive to the released
// credentialRef-based MailThrottler contract.
type ResolvedMailThrottler interface {
	connector_throttle.ResolvedThrottler
}

// MailPreparer binds a provider-neutral mail intent before the Worker records
// its durable dispatch checkpoint. It deliberately defers principal, token,
// throttle, and provider I/O to the prepared effect.
type MailPreparer struct {
	authority         MailAuthority
	resolvedAuthority ResolvedMailAuthority
	oauth             MailOAuthResolver
	providers         MailProviderResolver
	attachments       MailAttachmentReader

	throttler         MailThrottler
	resolvedThrottler ResolvedMailThrottler
}

func NewMailPreparer(
	authority MailAuthority,
	oauth MailOAuthResolver,
	providers MailProviderResolver,
	throttler MailThrottler,
) (*MailPreparer, error) {
	if authority == nil || oauth == nil || providers == nil || throttler == nil {
		return nil, ErrDependency
	}
	return &MailPreparer{authority: authority, oauth: oauth, providers: providers, throttler: throttler}, nil
}

// NewResolvedMailPreparer binds mail throttling to the credential identity
// already proven by MailAuthority. NewMailPreparer remains available for
// existing consumers at the released credentialRef-based compatibility seam.
func NewResolvedMailPreparer(
	authority ResolvedMailAuthority,
	oauth MailOAuthResolver,
	providers MailProviderResolver,
	throttler ResolvedMailThrottler,
) (*MailPreparer, error) {
	return newResolvedMailPreparer(authority, oauth, providers, throttler, nil)
}

func NewResolvedMailPreparerWithAttachments(
	authority ResolvedMailAuthority,
	oauth MailOAuthResolver,
	providers MailProviderResolver,
	throttler ResolvedMailThrottler,
	attachments MailAttachmentReader,
) (*MailPreparer, error) {
	if attachments == nil {
		return nil, ErrDependency
	}
	return newResolvedMailPreparer(authority, oauth, providers, throttler, attachments)
}

func newResolvedMailPreparer(
	authority ResolvedMailAuthority,
	oauth MailOAuthResolver,
	providers MailProviderResolver,
	throttler ResolvedMailThrottler,
	attachments MailAttachmentReader,
) (*MailPreparer, error) {
	if authority == nil || oauth == nil || providers == nil || throttler == nil {
		return nil, ErrDependency
	}
	return &MailPreparer{
		resolvedAuthority: authority, oauth: oauth, providers: providers,
		resolvedThrottler: throttler, attachments: attachments,
	}, nil
}

func (preparer *MailPreparer) Prepare(ctx context.Context, command Command) (PreparedEffect, error) {
	if preparer == nil || (preparer.authority == nil && preparer.resolvedAuthority == nil) ||
		preparer.oauth == nil || preparer.providers == nil ||
		(preparer.throttler == nil && preparer.resolvedThrottler == nil) || ctx == nil {
		return nil, ErrDependency
	}
	payload, err := decodeMailDelivery(command.Intent)
	if err != nil {
		return nil, &PreparationError{Code: "invalid_mail_intent", Cause: err}
	}
	var binding MailBinding
	var credential connector_throttle.ResolvedCredential
	if preparer.resolvedAuthority != nil {
		resolved, resolveErr := preparer.resolvedAuthority.ResolveResolvedMail(ctx, command)
		if resolveErr != nil {
			return nil, resolveErr
		}
		binding, credential = resolved.MailBinding, resolved.Credential
	} else {
		binding, err = preparer.authority.ResolveMail(ctx, command)
		if err != nil {
			return nil, err
		}
	}
	if !canonicalMailBinding(&binding) {
		return nil, &PreparationError{Code: "invalid_mail_binding", Cause: ErrIdentityConflict}
	}
	if preparer.resolvedThrottler != nil && !canonicalResolvedMailCredential(credential) {
		return nil, &PreparationError{Code: "invalid_mail_binding", Cause: ErrIdentityConflict}
	}
	return &mailEffect{
		oauth: preparer.oauth, providers: preparer.providers,
		throttler: preparer.throttler, resolvedThrottler: preparer.resolvedThrottler,
		resolvedAuthority: preparer.resolvedAuthority,
		connectorKey:      binding.ConnectorKey, credentialRef: binding.CredentialRef, credential: credential,
		endpointClass: binding.EndpointClass, requiredScopes: append([]string(nil), binding.RequiredScopes...),
		actorID: payload.AuthorizedActorID,
		message: connector_mail.Message{
			ToAddresses: append([]string(nil), payload.ToAddresses...),
			Subject:     payload.Subject, TextBody: payload.TextBody,
		},
		ccAddresses:          append([]string(nil), payload.CcAddresses...),
		bccAddresses:         append([]string(nil), payload.BccAddresses...),
		htmlBody:             payload.HTMLBody,
		payloadFormatVersion: command.Intent.PayloadFormatVersion,
		attachments:          preparer.attachments, attachmentRefs: append([]outboundintentv1.MailAttachmentV1(nil), payload.Attachments...),
		attachmentRequest: outboundintentv1.OpenMailAttachmentRequest{
			IntentID: command.Intent.IntentID, PayloadDigest: command.Intent.PayloadDigest,
			CatalogRevision: command.Intent.CatalogRevision, IntegrationCommandID: command.CommandID,
		},
	}, nil
}

type decodedMailDelivery struct {
	AuthorizedActorID string
	ToAddresses       []string
	CcAddresses       []string
	BccAddresses      []string
	Subject           string
	TextBody          string
	HTMLBody          string
	Attachments       []outboundintentv1.MailAttachmentV1
}

func decodeMailDelivery(intent outboundintentv1.Intent) (decodedMailDelivery, error) {
	switch intent.PayloadFormatVersion {
	case outboundintentv1.MailPayloadFormatV1:
		payload, err := outboundintentv1.DecodeMailDeliveryV1(intent)
		if err != nil {
			return decodedMailDelivery{}, err
		}
		return decodedMailDelivery{
			AuthorizedActorID: payload.AuthorizedActorID,
			ToAddresses:       payload.ToAddresses, Subject: payload.Subject, TextBody: payload.TextBody,
		}, nil
	case outboundintentv1.MailPayloadFormatV2:
		payload, err := outboundintentv1.DecodeMailDeliveryV2(intent)
		if err != nil {
			return decodedMailDelivery{}, err
		}
		return decodedMailDelivery{
			AuthorizedActorID: payload.AuthorizedActorID,
			ToAddresses:       payload.ToAddresses, CcAddresses: payload.CcAddresses,
			BccAddresses: payload.BccAddresses, Subject: payload.Subject,
			TextBody: payload.TextBody, HTMLBody: payload.HTMLBody,
		}, nil
	case outboundintentv1.MailPayloadFormatV3:
		payload, err := outboundintentv1.DecodeMailDeliveryV3(intent)
		if err != nil {
			return decodedMailDelivery{}, err
		}
		return decodedMailDelivery{
			AuthorizedActorID: payload.AuthorizedActorID,
			ToAddresses:       payload.ToAddresses, CcAddresses: payload.CcAddresses,
			BccAddresses: payload.BccAddresses, Subject: payload.Subject,
			TextBody: payload.TextBody, HTMLBody: payload.HTMLBody,
			Attachments: append([]outboundintentv1.MailAttachmentV1(nil), payload.Attachments...),
		}, nil
	default:
		return decodedMailDelivery{}, ErrIdentityConflict
	}
}

type mailEffect struct {
	oauth     MailOAuthResolver
	providers MailProviderResolver

	throttler         MailThrottler
	resolvedThrottler ResolvedMailThrottler
	resolvedAuthority ResolvedMailAuthority

	connectorKey         string
	credentialRef        string
	credential           connector_throttle.ResolvedCredential
	endpointClass        string
	requiredScopes       []string
	actorID              string
	message              connector_mail.Message
	payloadFormatVersion uint32
	ccAddresses          []string
	bccAddresses         []string
	htmlBody             string
	attachments          MailAttachmentReader
	attachmentRefs       []outboundintentv1.MailAttachmentV1
	attachmentRequest    outboundintentv1.OpenMailAttachmentRequest
}

func (effect *mailEffect) openAttachments(ctx context.Context) ([]connector_mail.Attachment, error) {
	if effect == nil || len(effect.attachmentRefs) == 0 {
		return nil, nil
	}
	if effect.attachments == nil {
		return nil, ErrDependency
	}
	result := make([]connector_mail.Attachment, 0, len(effect.attachmentRefs))
	for index, expected := range effect.attachmentRefs {
		request := effect.attachmentRequest
		request.AttachmentIndex = uint32(index)
		opened, err := effect.attachments.OpenOutboundMailAttachment(ctx, request, expected)
		if err != nil {
			clearMailAttachments(result)
			clearMailAttachmentData(opened.Data)
			return nil, err
		}
		if outboundintentv1.ValidateOpenedMailAttachment(request, expected, opened) != nil {
			clearMailAttachments(result)
			clearMailAttachmentData(opened.Data)
			return nil, ErrIdentityConflict
		}
		result = append(result, connector_mail.Attachment{
			FileName: expected.FileName, ContentType: expected.ContentType,
			Data: opened.Data,
		})
	}
	return result, nil
}

func clearMailAttachmentData(data []byte) {
	for index := range data {
		data[index] = 0
	}
}

func clearMailAttachments(attachments []connector_mail.Attachment) {
	for index := range attachments {
		for byteIndex := range attachments[index].Data {
			attachments[index].Data[byteIndex] = 0
		}
	}
}

// Dispatch cannot safely execute a typed mail effect because it has no owner
// for the terminal-result checkpoint. The Worker calls the additive typed
// interface below instead.
func (*mailEffect) Dispatch(context.Context) EffectResult {
	return EffectResult{Outcome: EffectUncertain, FailureCode: "typed_result_checkpoint_owner_missing"}
}

func (effect *mailEffect) DispatchWithTypedTerminalResultCheckpoint(
	ctx context.Context,
	checkpoint TypedTerminalResultCheckpoint,
) EffectResult {
	if effect == nil || effect.oauth == nil || effect.providers == nil ||
		(effect.throttler == nil && effect.resolvedThrottler == nil) ||
		ctx == nil || checkpoint == nil {
		return EffectResult{Outcome: EffectUncertain, FailureCode: "typed_result_checkpoint_owner_missing"}
	}
	provider, ok := effect.providers.MailProvider(effect.connectorKey)
	if !ok || provider == nil {
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
	}
	var providerV2 connector_mail.ProviderV2
	var providerV3 connector_mail.ProviderV3
	if effect.payloadFormatVersion == outboundintentv1.MailPayloadFormatV2 {
		var supportsV2 bool
		providerV2, supportsV2 = provider.(connector_mail.ProviderV2)
		if !supportsV2 {
			return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
		}
	} else if effect.payloadFormatVersion == outboundintentv1.MailPayloadFormatV3 {
		var supportsV3 bool
		providerV3, supportsV3 = provider.(connector_mail.ProviderV3)
		if !supportsV3 || effect.attachments == nil || len(effect.attachmentRefs) == 0 {
			return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
		}
	}
	loadedAttachments, err := effect.openAttachments(ctx)
	if err != nil {
		if terminalMailAttachmentFailure(err) {
			return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureAttachmentUnavailable))
		}
		return EffectResult{Outcome: EffectNotDispatched, FailureCode: "mail_attachment_unavailable"}
	}
	defer clearMailAttachments(loadedAttachments)
	providerTerminationBound := provider.EffectTerminationBound()
	if providerTerminationBound <= 0 {
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
	}
	principal, err := effect.oauth.Principal(ctx, effect.actorID, effect.connectorKey)
	if err != nil || principal == nil {
		return effect.finishOAuthFailure(ctx, checkpoint, err)
	}
	if principal.UserID != effect.actorID || principal.ConnectorKey != effect.connectorKey || principal.Generation < 1 ||
		principal.State != connector_oauth.PrincipalConnected {
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureRetired))
	}
	var wait time.Duration
	var release func()
	if effect.resolvedThrottler != nil {
		wait, release, err = effect.resolvedThrottler.ThrottleResolved(ctx, effect.credential, effect.endpointClass)
	} else {
		wait, release, err = effect.throttler.Throttle(ctx, effect.credentialRef, effect.endpointClass)
	}
	if release != nil {
		defer release()
	}
	if errors.Is(err, connector_throttle.ErrCredentialNotAvailable) || errors.Is(err, connector_throttle.ErrInvalidEndpointClass) {
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
	}
	if err != nil || release == nil {
		return EffectResult{Outcome: EffectNotDispatched, FailureCode: "mail_throttle_unavailable"}
	}
	if !waitForMailThrottle(ctx, wait) {
		return EffectResult{Outcome: EffectNotDispatched, FailureCode: "mail_throttle_unavailable"}
	}
	if effect.resolvedAuthority != nil {
		binding := ResolvedMailBinding{
			MailBinding: MailBinding{
				ConnectorKey: effect.connectorKey, CredentialRef: effect.credentialRef,
				EndpointClass:  effect.endpointClass,
				RequiredScopes: append([]string(nil), effect.requiredScopes...),
			},
			Credential: effect.credential,
		}
		if revalidateErr := effect.resolvedAuthority.RevalidateResolvedMail(ctx, binding); revalidateErr != nil {
			var preparation *PreparationError
			if errors.As(revalidateErr, &preparation) && preparation != nil && !preparation.Retryable {
				return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
			}
			return EffectResult{Outcome: EffectNotDispatched, FailureCode: "mail_binding_unavailable"}
		}
	}
	accessToken, err := effect.resolveAccessToken(ctx, principal.Generation)
	if err != nil || strings.TrimSpace(accessToken) == "" {
		return effect.finishOAuthFailure(ctx, checkpoint, err)
	}
	defer func() { accessToken = "" }()
	providerCtx, cancelProvider, ok := mailProviderContext(ctx, providerTerminationBound)
	if !ok {
		return EffectResult{Outcome: EffectNotDispatched, FailureCode: "mail_provider_window_unavailable"}
	}
	defer cancelProvider()
	message := effect.message
	message.FromAddress = principal.PrincipalAddress
	message.ToAddresses = append([]string(nil), effect.message.ToAddresses...)
	var providerResult connector_mail.DispatchResult
	var providerErr error
	if effect.payloadFormatVersion == outboundintentv1.MailPayloadFormatV3 {
		providerResult, providerErr = providerV3.DispatchV3(providerCtx, accessToken, connector_mail.MessageV3{
			MessageV2: connector_mail.MessageV2{
				Message: message, CcAddresses: append([]string(nil), effect.ccAddresses...),
				BccAddresses: append([]string(nil), effect.bccAddresses...), HTMLBody: effect.htmlBody,
			},
			Attachments: loadedAttachments,
		})
	} else if effect.payloadFormatVersion == outboundintentv1.MailPayloadFormatV2 {
		providerResult, providerErr = providerV2.DispatchV2(providerCtx, accessToken, connector_mail.MessageV2{
			Message: message, CcAddresses: append([]string(nil), effect.ccAddresses...),
			BccAddresses: append([]string(nil), effect.bccAddresses...), HTMLBody: effect.htmlBody,
		})
	} else {
		providerResult, providerErr = provider.Dispatch(providerCtx, accessToken, message)
	}
	cancelProvider()
	status := safeMailStatus(providerResult.ResponseStatus)
	if providerErr != nil {
		var failure *connector_mail.ProviderError
		if errors.As(providerErr, &failure) && failure != nil {
			switch failure.Kind {
			case connector_mail.ProviderNotDispatched:
				return EffectResult{Outcome: EffectNotDispatched, ResponseStatus: status, FailureCode: "mail_provider_not_dispatched"}
			case connector_mail.ProviderRejected:
				return effect.finish(ctx, checkpoint, status, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
			case connector_mail.ProviderAuthorization:
				return effect.finish(ctx, checkpoint, status, rejectedMailResult(outboundintentv1.MailFailureScope))
			}
		}
		return effect.finish(ctx, checkpoint, status, unknownMailResult())
	}
	delivered := outboundintentv1.MailDeliveryResultV1{
		Version: outboundintentv1.MailResultFormatV1, Outcome: outboundintentv1.MailOutcomeDelivered,
		RemoteMessageID: providerResult.RemoteMessageID, SenderAddress: principal.PrincipalAddress,
	}
	return effect.finish(ctx, checkpoint, status, delivered)
}

func terminalMailAttachmentFailure(err error) bool {
	if errors.Is(err, ErrIdentityConflict) {
		return true
	}
	var failure *commonv1.Failure
	if !errors.As(err, &failure) || failure == nil {
		return false
	}
	switch failure.Category {
	case commonv1.FailureInvalidRequest,
		commonv1.FailureUnauthenticated,
		commonv1.FailureForbidden,
		commonv1.FailureMissing,
		commonv1.FailureConflict,
		commonv1.FailureIncompatible:
		return true
	default:
		return false
	}
}

func (effect *mailEffect) resolveAccessToken(ctx context.Context, generation int64) (string, error) {
	request := connector_oauth.ResolveScopedAccessTokenRequest{
		UserID: effect.actorID, ConnectorKey: effect.connectorKey, ExpectedGeneration: generation,
		RequiredScopes: append([]string(nil), effect.requiredScopes...),
	}
	accessToken, err := effect.oauth.ResolveScopedAccessToken(ctx, request)
	if errors.Is(err, connector_oauth.ErrEffectResultStaged) {
		return effect.oauth.ResolveScopedAccessToken(ctx, request)
	}
	return accessToken, err
}

func (effect *mailEffect) finishOAuthFailure(
	ctx context.Context,
	checkpoint TypedTerminalResultCheckpoint,
	err error,
) EffectResult {
	switch {
	case errors.Is(err, connector_oauth.ErrPrincipalNotFound):
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureNotConnected))
	case errors.Is(err, connector_oauth.ErrGenerationMismatch), errors.Is(err, connector_oauth.ErrReconnectRequired),
		errors.Is(err, connector_oauth.ErrCiphertextInvalid):
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureRetired))
	case errors.Is(err, connector_oauth.ErrScopeMismatch):
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureScope))
	case errors.Is(err, connector_oauth.ErrInvalidInput), errors.Is(err, connector_oauth.ErrEffectStateInvalid),
		errors.Is(err, connector_oauth.ErrManualActionRequired), errors.Is(err, connector_oauth.ErrAuthorizationDenied):
		return effect.finish(ctx, checkpoint, 0, rejectedMailResult(outboundintentv1.MailFailureProviderRejected))
	default:
		return EffectResult{Outcome: EffectNotDispatched, FailureCode: "mail_oauth_unavailable"}
	}
}

func (*mailEffect) finish(
	ctx context.Context,
	checkpoint TypedTerminalResultCheckpoint,
	status int,
	result outboundintentv1.MailDeliveryResultV1,
) EffectResult {
	status = safeMailStatus(status)
	if result.Outcome == outboundintentv1.MailOutcomeDelivered && (status < 200 || status >= 300) {
		result = unknownMailResult()
	}
	raw, err := json.Marshal(result)
	if err != nil {
		raw, _ = json.Marshal(unknownMailResult())
	}
	if _, err := outboundintentv1.DecodeMailDeliveryResultV1(raw); err != nil {
		raw, _ = json.Marshal(unknownMailResult())
	}
	terminal := TypedTerminalResult{
		ResultFormatVersion: outboundintentv1.MailResultFormatV1,
		CanonicalResult:     append([]byte(nil), raw...),
	}
	checkpointCtx, cancelCheckpoint, ok := mailCheckpointContext(ctx)
	if !ok {
		return EffectResult{Outcome: EffectUncertain, ResponseStatus: status, FailureCode: "typed_result_checkpoint_failed"}
	}
	defer cancelCheckpoint()
	if err := checkpoint(checkpointCtx, status, terminal); err != nil {
		return EffectResult{Outcome: EffectUncertain, ResponseStatus: status, FailureCode: "typed_result_checkpoint_failed"}
	}
	return EffectResult{Outcome: EffectTypedTerminal, ResponseStatus: status}
}

func rejectedMailResult(code string) outboundintentv1.MailDeliveryResultV1 {
	return outboundintentv1.MailDeliveryResultV1{
		Version: outboundintentv1.MailResultFormatV1, Outcome: outboundintentv1.MailOutcomeRejected,
		FailureCode: code,
	}
}

func unknownMailResult() outboundintentv1.MailDeliveryResultV1 {
	return outboundintentv1.MailDeliveryResultV1{
		Version: outboundintentv1.MailResultFormatV1, Outcome: outboundintentv1.MailOutcomeUnknown,
		FailureCode: outboundintentv1.MailFailureOutcomeUnknown,
	}
}

func waitForMailThrottle(ctx context.Context, wait time.Duration) bool {
	if wait <= 0 {
		return ctx.Err() == nil
	}
	timer := time.NewTimer(wait)
	defer timer.Stop()
	select {
	case <-ctx.Done():
		return false
	case <-timer.C:
		return true
	}
}

func mailProviderContext(parent context.Context, terminationBound time.Duration) (context.Context, context.CancelFunc, bool) {
	if parent == nil || parent.Err() != nil || terminationBound <= 0 {
		return nil, nil, false
	}
	outerDeadline, ok := parent.Deadline()
	if !ok {
		return nil, nil, false
	}
	remaining := time.Until(outerDeadline)
	if remaining <= mailCheckpointReserve || terminationBound >= remaining-mailCheckpointReserve {
		return nil, nil, false
	}
	providerDeadline := outerDeadline.Add(-terminationBound - mailCheckpointReserve)
	if !providerDeadline.After(time.Now()) {
		return nil, nil, false
	}
	providerCtx, cancel := context.WithDeadline(parent, providerDeadline)
	return providerCtx, cancel, true
}

func mailCheckpointContext(dispatch context.Context) (context.Context, context.CancelFunc, bool) {
	if dispatch == nil {
		return nil, nil, false
	}
	outerDeadline, ok := dispatch.Deadline()
	if !ok {
		return nil, nil, false
	}
	now := time.Now()
	if !outerDeadline.After(now) {
		return nil, nil, false
	}
	checkpointDeadline := now.Add(mailCheckpointReserve)
	if outerDeadline.Before(checkpointDeadline) {
		checkpointDeadline = outerDeadline
	}
	checkpointCtx, cancel := context.WithDeadline(context.WithoutCancel(dispatch), checkpointDeadline)
	return checkpointCtx, cancel, true
}

func canonicalMailBinding(binding *MailBinding) bool {
	if binding == nil || !boundedMailBindingValue(binding.ConnectorKey, maxMailBindingValueBytes) ||
		!boundedMailBindingValue(binding.CredentialRef, maxMailBindingValueBytes) ||
		!boundedMailBindingValue(binding.EndpointClass, maxMailBindingValueBytes) {
		return false
	}
	return canonicalMailScopes(&binding.RequiredScopes)
}

func canonicalResolvedMailCredential(credential connector_throttle.ResolvedCredential) bool {
	return boundedMailBindingValue(credential.CanonicalID, maxMailBindingValueBytes) &&
		boundedMailBindingValue(credential.Namespace, maxMailBindingValueBytes)
}

func canonicalMailScopes(scopes *[]string) bool {
	if scopes == nil || len(*scopes) == 0 || len(*scopes) > maxMailScopeCount {
		return false
	}
	seen := make(map[string]struct{}, len(*scopes))
	for _, scope := range *scopes {
		if !boundedMailBindingValue(scope, maxMailScopeBytes) || strings.IndexFunc(scope, unicode.IsSpace) >= 0 {
			return false
		}
		if _, duplicate := seen[scope]; duplicate {
			return false
		}
		seen[scope] = struct{}{}
	}
	*scopes = append([]string(nil), (*scopes)...)
	sort.Strings(*scopes)
	return true
}

func boundedMailBindingValue(value string, maximum int) bool {
	if value == "" || value != strings.TrimSpace(value) || len(value) > maximum || !utf8.ValidString(value) {
		return false
	}
	for _, current := range value {
		if unicode.IsControl(current) {
			return false
		}
	}
	return true
}

func safeMailStatus(status int) int {
	if status < 100 || status > 599 {
		return 0
	}
	return status
}

var _ Preparer = (*MailPreparer)(nil)
var _ TypedTerminalResultEffect = (*mailEffect)(nil)
