<?php

declare(strict_types=1);

namespace Drupal\flowdrop\DTO\Tool;

use Drupal\flowdrop\Service\Tool\ToolInvokerInterface;

/**
 * Immutable {@see ToolBindingInterface} value object.
 *
 * The definition fields are plain data (projected just-in-time from the tool
 * node); {@see self::invoke()} delegates to the orchestrator-owned invoker,
 * which is the authorization boundary.
 *
 * @api
 */
final class ToolBinding implements ToolBindingInterface {

  /**
   * Constructs a ToolBinding.
   *
   * @param string $name
   *   The model-facing tool name.
   * @param string $nodeId
   *   The tool node's ID (internal routing key).
   * @param string $description
   *   The tool description.
   * @param array<string, mixed> $inputSchema
   *   The tool's parameter schema.
   * @param string $displayTitle
   *   The "<label> (<nodeId>)" form for logs/traces.
   * @param \Drupal\flowdrop\Service\Tool\ToolInvokerInterface $invoker
   *   The orchestrator-owned invoker that runs the tool node.
   */
  public function __construct(
    private readonly string $name,
    private readonly string $nodeId,
    private readonly string $description,
    private readonly array $inputSchema,
    private readonly string $displayTitle,
    private readonly ToolInvokerInterface $invoker,
  ) {}

  /**
   * {@inheritdoc}
   */
  public function getName(): string {
    return $this->name;
  }

  /**
   * {@inheritdoc}
   */
  public function getNodeId(): string {
    return $this->nodeId;
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription(): string {
    return $this->description;
  }

  /**
   * {@inheritdoc}
   */
  public function getInputSchema(): array {
    return $this->inputSchema;
  }

  /**
   * {@inheritdoc}
   */
  public function getDisplayTitle(): string {
    return $this->displayTitle;
  }

  /**
   * {@inheritdoc}
   */
  public function toDefinition(): array {
    return [
      "name" => $this->name,
      "description" => $this->description,
      "input_schema" => $this->inputSchema,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function invoke(array $args): ToolResultInterface {
    return $this->invoker->invokeTool($this->nodeId, $args);
  }

}
