<?php

declare(strict_types=1);

final class MailTransportRegistry
{
    /** @var array<string, MailTransportInterface> */
    private array $transports = [];
    private string $activeSlug = 'smtp';

    public function registerCore(string $slug, MailTransportInterface $transport): void
    {
        $slug = strtolower(trim($slug));
        if (!preg_match('/^[a-z][a-z0-9_]*$/', $slug)) {
            throw new InvalidArgumentException('Core mail transport slug must be snake_case.');
        }
        $this->transports[$slug] = $transport;
    }

    public function registerExtension(string $vendor, string $slug, MailTransportInterface $transport): void
    {
        $vendor = strtolower(trim($vendor));
        $slug = strtolower(trim($slug));
        if (!preg_match('/^[a-z][a-z0-9_]*$/', $vendor) || !preg_match('/^[a-z][a-z0-9_]*$/', $slug)) {
            throw new InvalidArgumentException('Extension mail transport vendor and slug must be snake_case.');
        }
        $this->transports['x.' . $vendor . '.' . $slug] = $transport;
    }

    public function activeTransport(): MailTransportInterface
    {
        if (!isset($this->transports[$this->activeSlug])) {
            throw new RuntimeException('No active mail transport is registered.');
        }
        return $this->transports[$this->activeSlug];
    }

    /**
     * @return array<string, array<string, mixed>>
     */
    public function knownTransports(): array
    {
        $known = [];
        foreach ($this->transports as $slug => $transport) {
            $known[$slug] = $transport->describe();
        }
        ksort($known);
        return $known;
    }
}
