<?php

/*
 * This file is part of the official PHP MCP SDK.
 *
 * A collaboration between Symfony and the PHP Foundation.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Matomo\Dependencies\McpServer\Mcp\Client\Transport;

use Matomo\Dependencies\McpServer\Mcp\Client\State\ClientStateInterface;
use Matomo\Dependencies\McpServer\Mcp\Exception\RuntimeException;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
/**
 * Base implementation for client transports.
 *
 * Provides callback management and common utilities.
 *
 * @author Kyrian Obikwelu <koshnawaza@gmail.com>
 */
abstract class BaseTransport implements TransportInterface
{
    /** @var callable(): mixed|null */
    protected $initializeCallback;
    /** @var callable(string): void|null */
    protected $messageCallback;
    /** @var callable(\Throwable): void|null */
    protected $errorCallback;
    /** @var callable(string): void|null */
    protected $closeCallback;
    protected ?ClientStateInterface $state = null;
    protected LoggerInterface $logger;
    public function __construct(?LoggerInterface $logger = null)
    {
        $this->logger = $logger ?? new NullLogger();
    }
    public function onInitialize(callable $listener) : void
    {
        $this->initializeCallback = $listener;
    }
    public function onMessage(callable $listener) : void
    {
        $this->messageCallback = $listener;
    }
    public function onError(callable $listener) : void
    {
        $this->errorCallback = $listener;
    }
    public function onClose(callable $listener) : void
    {
        $this->closeCallback = $listener;
    }
    public function setState(ClientStateInterface $state) : void
    {
        $this->state = $state;
    }
    /**
     * Perform initialization via the registered callback.
     *
     * @return mixed The result from the initialization callback
     *
     * @throws RuntimeException If no initialize listener is registered
     */
    protected function handleInitialize() : mixed
    {
        if (!\is_callable($this->initializeCallback)) {
            throw new RuntimeException('No initialize listener registered');
        }
        return ($this->initializeCallback)();
    }
    /**
     * Handle an incoming message from the server.
     */
    protected function handleMessage(string $message) : void
    {
        if (\is_callable($this->messageCallback)) {
            try {
                ($this->messageCallback)($message);
            } catch (\Throwable $e) {
                $this->handleError($e);
            }
        }
    }
    /**
     * Handle a transport error.
     */
    protected function handleError(\Throwable $error) : void
    {
        $this->logger->error('Transport error', ['exception' => $error]);
        if (\is_callable($this->errorCallback)) {
            ($this->errorCallback)($error);
        }
    }
    /**
     * Handle connection close.
     */
    protected function handleClose(string $reason) : void
    {
        $this->logger->info('Transport closed', ['reason' => $reason]);
        if (\is_callable($this->closeCallback)) {
            ($this->closeCallback)($reason);
        }
    }
}
