<?php

declare(strict_types=1);

namespace apexl\Io\modules\logger\services\handlerCreator;

use apexl\Io\modules\logger\dto\handlerConfig;
use apexl\Io\modules\logger\dto\handlerConfigParams\googleChatHandlerConfigParams;
use apexl\Io\modules\logger\dto\streamConfig;
use apexl\Io\modules\logger\handlers\googleChatHandler;
use Monolog\Handler\HandlerInterface;
use Monolog\Handler\NullHandler;

/**
 * Posts records to a Google Chat space through an incoming webhook.
 *
 * Monolog ships no Google Chat handler, so unlike the Slack creator this one builds
 * {@see googleChatHandler} rather than wrapping something from the library.
 */
final readonly class googleChatLogHandlerCreator extends handlerCreator
{
    public function create(
        string $streamName,
        handlerConfig $handlerConfig,
        streamConfig $streamConfig
    ): HandlerInterface {
        /** @var googleChatHandlerConfigParams $params */
        $params = $handlerConfig->params;
        $level = $this->level($handlerConfig, $streamConfig);

        if (!$params->webhook_url) {
            error_log(
                sprintf(
                    'The \'google_chat\' log handler on stream \'%s\' has no `webhook_url`; not posting',
                    $streamName
                )
            );

            return new NullHandler();
        }

        // As for Slack: without ext-curl the handler cannot post, and finding that out
        // by throwing while the logger is still being built would take down whatever was
        // being logged about. Logging failing must never be worse than the thing it was
        // reporting.
        if (!extension_loaded('curl')) {
            error_log(
                sprintf(
                    'The \'google_chat\' log handler on stream \'%s\' needs ext-curl; not posting',
                    $streamName
                )
            );

            return new NullHandler();
        }

        // Deliberately not wrapped in a BufferHandler, for the same reason as Slack:
        // one record is one message either way, so buffering would only delay them and
        // then release the backlog at once. Volume is controlled by the level, which is
        // why this belongs on error and above.
        return new googleChatHandler(
            $params->webhook_url,
            $params->subtitle ?? $streamName,
            $params->include_context,
            $params->exclude_fields,
            $params->thread_key,
            $level,
        );
    }
}
