<?php

use Illuminate\Support\Facades\File;

/**
 * A From address belongs to the account that signs in.
 *
 * Every purpose mailbox in this installation has its OWN SMTP account, and a
 * mail server lets an account send only from the address it owns. mailcow
 * answers anything else with "553 5.7.1 Sender address rejected: not owned by
 * user no-reply@…" — and it is right to.
 *
 * So a mail that takes its From from a mailbox has to go out over that mailbox's
 * mailer as well. Setting one and forgetting the other produces a mail that
 * renders perfectly, queues without complaint, and never arrives: InvoiceMail
 * and OrderConfirmationMail both addressed billing@ while going out over the
 * default mailer's no-reply@ login, which means no customer had ever received an
 * invoice mail or an order confirmation on a server that checks.
 */
it('gives every mail that takes a mailbox From the matching mailer', function () {
    $offenders = [];

    foreach (File::allFiles(app_path('Mail')) as $file) {
        $code = $file->getContents();

        // Only the ones that take their sender from a mailbox. A mailable with
        // no mailbox From has nothing to mismatch.
        if (! str_contains($code, 'mailboxEnvelope(') && ! str_contains($code, 'mailboxAddresses(')) {
            continue;
        }

        preg_match('/mailbox(?:Envelope|Addresses)\(\s*MailPurpose::([A-Z_]+)/', $code, $from);
        preg_match("/->mailer\('cp_'\.MailPurpose::([A-Z_]+)\)/", $code, $mailer);

        $fromPurpose = $from[1] ?? null;
        $mailerPurpose = $mailer[1] ?? null;

        if ($fromPurpose !== null && $fromPurpose !== $mailerPurpose) {
            $offenders[] = $file->getFilename().': From '.$fromPurpose.', mailer '.($mailerPurpose ?? 'DEFAULT');
        }
    }

    expect($offenders)->toBe([]);
});

it('sends each purpose over its own mailer, not over whatever mail.default is', function () {
    // The purpose mailers exist so that each mailbox authenticates as itself.
    // A mailable naming no mailer silently uses mail.default, which on this
    // installation is the plain smtp mailer with ONE account behind it.
    foreach (App\Services\Mail\MailPurpose::ALL as $purpose) {
        expect(config('mail.mailers.cp_'.$purpose))
            ->toBe(['transport' => 'mailbox', 'purpose' => $purpose]);
    }
});
