<?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\Capability\Registry;

use Matomo\Dependencies\McpServer\Mcp\Capability\Formatter\ToolResultFormatter;
use Matomo\Dependencies\McpServer\Mcp\Schema\Content\Content;
use Matomo\Dependencies\McpServer\Mcp\Schema\Tool;
/**
 * @phpstan-import-type Handler from ElementReference
 *
 * @author Kyrian Obikwelu <koshnawaza@gmail.com>
 */
class ToolReference extends ElementReference
{
    /**
     * @param Handler $handler
     */
    public function __construct(public readonly Tool $tool, callable|array|string $handler, bool $isManual = \false)
    {
        parent::__construct($handler, $isManual);
    }
    /**
     * Formats the result of a tool execution into an array of MCP Content items.
     *
     * - If the result is already a Content object, it's wrapped in an array.
     * - If the result is an array:
     *   - If all elements are Content objects, the array is returned as is.
     *   - If it's a mixed array (Content and non-Content items), non-Content items are
     *     individually formatted (scalars to TextContent, others to JSON TextContent).
     *   - If it's an array with no Content items, the entire array is JSON-encoded into a single TextContent.
     * - Scalars (string, int, float, bool) are wrapped in TextContent.
     * - null is represented as TextContent('(null)').
     * - Other objects are JSON-encoded and wrapped in TextContent.
     *
     * @param mixed $toolExecutionResult the raw value returned by the tool's PHP method
     *
     * @return Content[] the content items for CallToolResult
     *
     * @throws \JsonException if JSON encoding fails for non-Content array/object results
     */
    public function formatResult(mixed $toolExecutionResult) : array
    {
        return (new ToolResultFormatter())->format($toolExecutionResult);
    }
    /**
     * Extracts structured content from a tool result using the output schema.
     *
     * @param mixed $toolExecutionResult the raw value returned by the tool's PHP method
     *
     * @return array<string, mixed>|null the structured content, or null if not extractable
     *
     * @throws \JsonException if JSON encoding fails for non-Content array/object results
     */
    public function extractStructuredContent(mixed $toolExecutionResult) : ?array
    {
        if (\is_array($toolExecutionResult)) {
            return $toolExecutionResult;
        }
        if (\is_object($toolExecutionResult) && !$toolExecutionResult instanceof Content) {
            $jsonResult = json_encode($toolExecutionResult, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE | \JSON_THROW_ON_ERROR | \JSON_INVALID_UTF8_SUBSTITUTE);
            return json_decode($jsonResult, \true, 512, \JSON_THROW_ON_ERROR);
        }
        return null;
    }
}
