<?php

declare(strict_types=1);

namespace Drupal\flowdrop_runtime\Service\Tool;

use Drupal\flowdrop_runtime\DTO\Compiler\DependencyGraph;

/**
 * Resolves a consumer's tool wiring into a flat set of leaf tool nodes.
 *
 * A consumer's tools are its incoming tool_availability edges — but a tool
 * parent whose processor implements
 * {@see \Drupal\flowdrop\Plugin\FlowDropNodeProcessor\ToolPassthroughInterface}
 * (e.g. a ToolBox) is not a tool itself: it forwards the tools wired into it.
 * Flattening recurses through such passthrough nodes and returns only the
 * leaves, deduplicated by node ID (the same tool reached via two boxes is one
 * tool).
 *
 * Used by the runtime tool projector (the flattened set is both the projected
 * collection and the invoker allow-list — single source of truth) and by the
 * compiler's tool-wiring validation (name collisions are checked on the
 * flattened set).
 *
 * @internal
 *   Runtime wiring detail; not a stable API.
 */
interface ToolGraphFlattenerInterface {

  /**
   * Flattens a consumer's tool wiring into leaf tool node IDs.
   *
   * @param string $consumerNodeId
   *   The consumer node ID.
   * @param \Drupal\flowdrop_runtime\DTO\Compiler\DependencyGraph $graph
   *   The dependency graph.
   *
   * @return array<int, string>
   *   Leaf tool node IDs, deduplicated, in traversal order.
   *
   * @throws \Drupal\flowdrop_runtime\Exception\ToolWiringException
   *   On a passthrough cycle or when nesting exceeds the supported depth.
   */
  public function flattenLeafTools(string $consumerNodeId, DependencyGraph $graph): array;

  /**
   * Determines whether a node's processor is a tool passthrough.
   *
   * @param string $nodeId
   *   The node ID.
   * @param \Drupal\flowdrop_runtime\DTO\Compiler\DependencyGraph $graph
   *   The dependency graph.
   *
   * @return bool
   *   TRUE when the node's processor class implements ToolPassthroughInterface.
   *   FALSE when it does not, or when the class cannot be resolved (an
   *   unresolvable node is conservatively treated as a plain tool).
   */
  public function isPassthrough(string $nodeId, DependencyGraph $graph): bool;

}
