// Mail through Amazon SES: a receipt sent plainly, a message with an attachment built by hand, a
// template stored, filled in and sent to many, what the account may send, and SES's bounce and
// complaint notices read so that the addresses go off the list.
//
//   AWS_REGION=eu-west-1 AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... SES_FROM=shop@example.com quillo run aws_ses.qwe
//   then open http://localhost:8080/send, /raw, /template, /account and /notices
//
// POST /ses/notices takes what an SNS topic delivers. Check its signature first: the aws_sns plugin
// does that, and this file only reads. SES_API_URL reaches LocalStack or a test server.

use "aws_ses.qwer"

route GET /send = {
    id: ses_send({ to: "ada@example.com", subject: "Your receipt", text: "Thanks!", html: "<p>Thanks!</p>", tags: { kind: "receipt" } }, {})?,
    list: ses_send({ to: ["a@example.com", "b@example.com"], cc: "c@example.com", reply_to: "help@example.com", subject: "Grüße", text: "Hallo" }, {})?,
    no_body: ses_send({ to: "a@example.com", subject: "x" }, {}).error,
    too_many: ses_send({ to: map(range(0, 51), (i) => `u${i}@example.com`), subject: "x", text: "y" }, {}).error,
    unverified: ses_send({ from: "someone@not-verified.example", to: "a@example.com", subject: "x", text: "y" }, {}).error,
}

route GET /raw {
    let mail = { to: "ada@example.com", subject: "Facture n° 7 — été", text: "See attached.", html: "<p>See attached.</p>", attachments: [{ filename: "invoice.txt", content_type: "text/plain", data: "SW52b2ljZSA3Cg==" }] }
    let text = ses_raw_message(mail)?
    { id: ses_send_raw(mail, {})?, checked: http.get(env("SES_API_URL", "") + "/_last").json, multipart: contains(text, "multipart/mixed"), encoded: contains(text, "=?UTF-8?B?") }
}

route GET /template {
    ses_template_put("welcome", { subject: "Hello {{name}}", text: "Your code is {{code}}", html: "<b>{{code}}</b>" }, {})?
    ses_template_put("welcome", { subject: "Welcome {{name}}", text: "Your code is {{code}}", html: "<b>{{code}}</b>" }, {})?
    let kept = ses_template_get("welcome", {})?
    let rendered = ses_template_render("welcome", { name: "Ada", code: 77 }, {})?
    let sent = ses_send_template("welcome", { name: "Ada", code: 77 }, { to: "ada@example.com" }, {})?
    let bulk = ses_send_bulk("welcome", { name: "friend", code: 0 }, [{ to: "a@example.com", data: { name: "A", code: 1 } }, { to: "bounced@example.com", data: { name: "B", code: 2 } }], {}, {})?
    { subject: kept.subject, rendered: contains(rendered, "Your code is 77"), sent: len(sent) > 0, bulk: map(bulk, (b) => b.status), gone: ses_template_delete("welcome", {})?, missing: ses_template_get("welcome", {}).error }
}

route GET /account = {
    account: ses_account({})?,
    suppressed: ses_suppress("gone@example.com", "BOUNCE", {})?,
    why: ses_suppressed("gone@example.com", {})?.reason,
    bad_reason: ses_suppress("gone@example.com", "DISLIKE", {}).error,
    unlisted: ses_unsuppress("gone@example.com", {})?,
    fine: ses_suppressed("gone@example.com", {})?,
}

// The addresses that must not be mailed again.
route POST /ses/notices {
    let n = ses_notice(request.body)
    if is_err(n) { reply 400 n.error }
    { kind: n.kind, stop: n.stop ?? [] }
}

route GET /notices {
    let wrap = (m) => json.stringify({ Type: "Notification", MessageId: "sns-1", TopicArn: "arn:aws:sns:eu-west-1:1:ses", Message: json.stringify(m) })
    let mail = { messageId: "m-1", source: "shop@example.com", timestamp: "2026-11-01T09:00:00.000Z", commonHeaders: { subject: "Your receipt" } }
    let hard = ses_notice(wrap({ notificationType: "Bounce", mail, bounce: { bounceType: "Permanent", bounceSubType: "General", feedbackId: "f-1", bouncedRecipients: [{ emailAddress: "nobody@example.com", action: "failed", status: "5.1.1", diagnosticCode: "smtp; 550 5.1.1 user unknown" }] } }))?
    let soft = ses_notice(wrap({ eventType: "Bounce", mail, bounce: { bounceType: "Transient", bounceSubType: "MailboxFull", bouncedRecipients: [{ emailAddress: "full@example.com" }] } }))?
    let spam = ses_notice(json.stringify({ notificationType: "Complaint", mail, complaint: { complaintFeedbackType: "abuse", complainedRecipients: [{ emailAddress: "angry@example.com" }] } }))?
    let okay = ses_notice(wrap({ notificationType: "Delivery", mail, delivery: { recipients: ["ada@example.com"], smtpResponse: "250 ok", processingTimeMillis: 412 } }))?
    let sub = ses_notice(json.stringify({ Type: "SubscriptionConfirmation", TopicArn: "arn:aws:sns:eu-west-1:1:ses", SubscribeURL: "https://sns.eu-west-1.amazonaws.com/?Action=ConfirmSubscription", Token: "t" }))?
    {
        hard: hard,
        soft_stop: soft.stop,
        soft_permanent: soft.permanent,
        spam: { type: spam.type, stop: spam.stop },
        delivered: okay.recipients,
        subscribe: sub.subscribe_url,
        junk: ses_notice("{\"hello\":1}").error,
    }
}
