<?php

declare(strict_types=1);

namespace Drupal\flowdrop\Plugin\FlowDropNodeProcessor;

use Drupal\flowdrop\DTO\ParameterBagInterface;
use Drupal\flowdrop_orchestration\DTO\ResolvedInterruptInterface;

/**
 * Opt-in cleanup hook for nodes that hold external resources mid-interrupt.
 *
 * When an inward Cancel signal is processed for a pipeline, the runtime
 * auto-cancels any pending outward interrupts on it (so HITL prompts don't
 * sit forever in the inbox). Nodes that allocated external resources
 * before throwing the interrupt — a posted Slack approval message, an
 * open webhook subscription, a queued background job — implement this
 * interface to release those resources at the same time.
 *
 * The runtime calls `cancel()` ONLY when an inward Cancel signal triggers
 * auto-cancellation of an outward interrupt belonging to a node that
 * implements this interface. Outward interrupts cancelled by other means
 * (expired, manually cancelled through the inbox, etc.) do NOT trigger
 * this hook — the contract is specifically about pipeline-level cancellation.
 *
 * Implementations MUST NOT throw. The runtime catches exceptions and
 * logs them, then proceeds with the cancellation regardless — teardown
 * is best-effort, since by the time it runs the pipeline is already
 * being torn down and a failing cleanup shouldn't block that.
 *
 * @api
 */
interface CancellableNodeProcessorInterface {

  /**
   * Releases external resources held by this node.
   *
   * @param \Drupal\flowdrop_orchestration\DTO\ResolvedInterruptInterface $interrupt
   *   The interrupt being cancelled. Read its context/responseData (if
   *   any) for cleanup hints. The interrupt entity has just transitioned
   *   to status `cancelled` — implementations should treat it as
   *   read-only state describing what they need to clean up.
   * @param \Drupal\flowdrop\DTO\ParameterBagInterface $params
   *   The parameter bag the node received on its initial execution (the
   *   one that threw the interrupt). Built from `job.getInputData()` —
   *   the orchestrator does not rebuild upstream values for cancel().
   */
  public function cancel(
    ResolvedInterruptInterface $interrupt,
    ParameterBagInterface $params,
  ): void;

}
