<?php

declare(strict_types=1);

namespace Drupal\flowdrop_runtime\Service\Runtime;

use Drupal\flowdrop\DTO\Tool\ToolCollectionInterface;
use Drupal\flowdrop\DTO\ValidationResult;
use Drupal\flowdrop_runtime\DTO\Runtime\NodeExecutionContext;
use Drupal\flowdrop_runtime\DTO\Runtime\NodeExecutionResult;
use Drupal\flowdrop_runtime\Service\Logging\ExecutionLoggerInterface;

/**
 * Interface for the core node runtime service.
 *
 * Provides methods for executing workflow nodes and accessing
 * execution infrastructure.
 *
 * @internal This interface is not part of the public API and may change without notice.
 */
interface NodeRuntimeServiceInterface {

  /**
   * Execute a single node with real-time updates.
   *
   * @param string $executionId
   *   The execution ID.
   * @param string $nodeId
   *   The node instance ID.
   * @param string $nodeType
   *   The node type ID (FlowDropNodeType entity ID).
   * @param array<string, mixed> $runtimeInputs
   *   Runtime inputs from upstream connections.
   * @param array<string, mixed> $workflowValues
   *   Workflow-level configuration values.
   * @param \Drupal\flowdrop_runtime\DTO\Runtime\NodeExecutionContext $context
   *   The execution context.
   * @param \Drupal\flowdrop\DTO\Tool\ToolCollectionInterface|null $tools
   *   The tools wired to this node, injected into the processor when it
   *   implements ToolsAwareInterface. NULL when the node has no tools.
   * @param callable|null $configureProcessor
   *   Optional hook called with the processor instance after the built-in
   *   capability injection (execution context, tools) and before parameter
   *   resolution. Lets orchestrators inject orchestrator-specific
   *   capabilities (e.g. StateGraph state via StateAwareProcessorInterface)
   *   without the runtime depending on those modules.
   *
   * @return \Drupal\flowdrop_runtime\DTO\Runtime\NodeExecutionResult
   *   The execution result.
   *
   * @throws \Drupal\flowdrop_runtime\Exception\RuntimeException
   *   When node execution fails.
   */
  public function executeNode(
    string $executionId,
    string $nodeId,
    string $nodeType,
    array $runtimeInputs,
    array $workflowValues,
    NodeExecutionContext $context,
    ?ToolCollectionInterface $tools = NULL,
    ?callable $configureProcessor = NULL,
  ): NodeExecutionResult;

  /**
   * Execute multiple nodes in sequence with real-time updates.
   *
   * @param string $executionId
   *   The execution ID.
   * @param array<array<string, mixed>> $nodes
   *   Array of node definitions with 'id', 'type', 'inputs', and 'config'.
   * @param \Drupal\flowdrop_runtime\DTO\Runtime\NodeExecutionContext $context
   *   The execution context.
   *
   * @return array<string, \Drupal\flowdrop_runtime\DTO\Runtime\NodeExecutionResult>
   *   Array of execution results keyed by node ID.
   */
  public function executeNodes(
    string $executionId,
    array $nodes,
    NodeExecutionContext $context,
  ): array;

  /**
   * Validate node before execution.
   *
   * @param string $executionId
   *   The execution ID for logging.
   * @param string $nodeId
   *   The node instance ID for logging.
   * @param string $nodeType
   *   The node type ID.
   * @param array<string, mixed> $params
   *   The parameters to validate.
   *
   * @return \Drupal\flowdrop\DTO\ValidationResult
   *   The validation result.
   */
  public function validateNode(
    string $executionId,
    string $nodeId,
    string $nodeType,
    array $params,
  ): ValidationResult;

  /**
   * Get node processor information.
   *
   * @param string $nodeType
   *   The node type ID.
   *
   * @return array<string, mixed>
   *   Node processor information.
   */
  public function getNodeProcessorInfo(string $nodeType): array;

  /**
   * Get the execution logger.
   *
   * @return \Drupal\flowdrop_runtime\Service\Logging\ExecutionLoggerInterface
   *   The execution logger.
   */
  public function getExecutionLogger(): ExecutionLoggerInterface;

}
