<?php

namespace App\Support;

use App\Mail\Transport\MailboxTransport;

/**
 * Whether this installation really sends mail — stored, not only in the .env.
 *
 * Everything else about the mail stack has been a console setting for a while:
 * the server, the port, the encryption, the sender addresses, the credentials
 * per mailbox. `mail.default` was the one value left that could only be changed
 * by editing a file and restarting workers — while the readiness page reported
 * its state as BLOCKING, with no control behind the "Beheben" link and no way
 * to say what it should be set to. "Anything that is not log or array" is not
 * an instruction; it is the question handed back to the operator.
 *
 * TWO STATES, not a driver picker. What actually sends is MailboxTransport,
 * using the stored server details and each mailbox's own credentials; this
 * decides only whether it delegates to that or writes to the log. Offering a
 * list of Symfony transports here would suggest the choice does something it
 * does not.
 *
 * NOT scoped to the operating mode. A test-mode installation still has to be
 * able to send a real mail — that is how an operator checks the thing works
 * before the first customer — and a live one still has to be able to be muted
 * while it is being set up. Which of the two is on is a property of the
 * installation, not of the mode it is trading in.
 */
final class MailDelivery
{
    public const SETTING = 'mail.transport';

    /** What is stored when an operator switches delivery ON. */
    public const DELIVERING = 'smtp';

    /** What is stored when they switch it OFF: written, never sent. */
    public const MUTED = 'log';

    /**
     * The transport in force.
     *
     * Falls back to `config('mail.default')` — i.e. MAIL_MAILER — when nothing
     * has been stored, so an installation that was set up before this existed,
     * or one deployed with the line in its .env, keeps behaving exactly as it
     * did. The setting is an override, not a replacement.
     */
    public static function transport(): ?string
    {
        $stored = Settings::get(self::SETTING);

        return filled($stored) ? (string) $stored : config('mail.default');
    }

    /**
     * Does mail leave this server?
     *
     * Asks MailboxTransport's own list rather than carrying a second, narrower
     * copy of it — `!== 'log'` once called `array` a delivering transport,
     * which delegate() has never agreed with.
     */
    public static function delivers(): bool
    {
        return ! in_array(self::transport(), MailboxTransport::NON_DELIVERING, true);
    }

    public static function set(bool $delivers): void
    {
        Settings::set(self::SETTING, $delivers ? self::DELIVERING : self::MUTED);
    }
}
