<?php

declare(strict_types=1);

namespace Drupal\flowdrop_orchestration\Service\Orchestrator;

use Drupal\flowdrop_orchestration\Plugin\Orchestrator\OrchestratorPluginInterface;

/**
 * Interface for the orchestrator helper service.
 *
 * Provides centralized orchestrator-related functionality including:
 * - Instance creation with fallback handling
 * - Default orchestrator resolution based on context
 * - Form options building for UI components
 * - Orchestrator type validation and detection.
 *
 * This service abstracts common orchestrator interaction patterns that were
 * previously duplicated across multiple modules, ensuring consistent behavior
 * and reducing maintenance burden.
 *
 * @see \Drupal\flowdrop_orchestration\Service\Orchestrator\OrchestratorHelper
 * @see \Drupal\flowdrop_orchestration\Service\Orchestrator\OrchestratorPluginManager
 *
 * @internal
 *   This class is not part of the public API and may change without notice.
 */
interface OrchestratorHelperInterface {

  /**
   * Namespaced ID for the synchronous orchestrator.
   *
   * Executes workflows directly in the current request without pipeline
   * entities. Best for presave events and operations requiring immediate
   * completion.
   */
  public const SYNCHRONOUS = "flowdrop_runtime:synchronous";

  /**
   * Namespaced ID for the synchronous pipeline orchestrator.
   *
   * Executes workflows synchronously using pipeline entities with job
   * tracking. Provides better visibility and debugging capabilities.
   */
  public const SYNCHRONOUS_PIPELINE = "flowdrop_runtime:synchronous_pipeline";

  /**
   * Namespaced ID for the asynchronous orchestrator.
   *
   * Queues workflows for background processing via Drupal's queue system.
   * Best for non-blocking operations and high-volume scenarios.
   */
  public const ASYNCHRONOUS = "flowdrop_runtime:asynchronous";

  /**
   * Namespaced ID for the StateGraph orchestrator.
   *
   * Provides stateful graph execution with checkpointing, reducers, and
   * human-in-the-loop support. Best for complex workflows requiring state
   * management and conversation continuity.
   */
  public const STATEGRAPH = "flowdrop_stategraph:stategraph";

  /**
   * Gets an orchestrator instance with fallback handling.
   *
   * Attempts to create an instance of the specified orchestrator type. If the
   * type is not available, falls back to the specified fallback type (or
   * ASYNCHRONOUS if not specified).
   *
   * @param string $type
   *   The orchestrator type (namespaced ID).
   * @param string|null $fallback
   *   Optional fallback orchestrator type. Defaults to ASYNCHRONOUS.
   *
   * @return \Drupal\flowdrop_orchestration\Plugin\Orchestrator\OrchestratorPluginInterface
   *   The orchestrator plugin instance.
   */
  public function getInstance(string $type, ?string $fallback = NULL): OrchestratorPluginInterface;

  /**
   * Gets an orchestrator instance from a settings array.
   *
   * Convenience method that extracts the orchestrator type from a settings
   * array (typically from trigger or session configuration) and creates the
   * appropriate instance with fallback handling.
   *
   * @param array<string, mixed> $settings
   *   The settings array containing a "type" key with the orchestrator type.
   * @param string|null $defaultType
   *   Default type if "type" key is missing. Defaults to ASYNCHRONOUS.
   *
   * @return \Drupal\flowdrop_orchestration\Plugin\Orchestrator\OrchestratorPluginInterface
   *   The orchestrator plugin instance.
   */
  public function getInstanceFromSettings(
    array $settings,
    ?string $defaultType = NULL,
  ): OrchestratorPluginInterface;

  /**
   * Resolves the default orchestrator based on context.
   *
   * Implements the multi-level resolution chain:
   * 1. If event type specified, uses event type's default orchestrator
   * 2. Falls back to general settings default orchestrator
   * 3. Overrides with SYNCHRONOUS for presave events
   * 4. Uses ASYNCHRONOUS as final fallback if resolved type is unavailable.
   *
   * @param string|null $eventType
   *   Optional event type ID for context-aware resolution.
   *
   * @return string
   *   The resolved orchestrator type (namespaced ID).
   */
  public function resolveDefault(?string $eventType = NULL): string;

  /**
   * Validates that an orchestrator type exists.
   *
   * @param string $type
   *   The orchestrator type to validate (namespaced ID).
   *
   * @return bool
   *   TRUE if the orchestrator type exists, FALSE otherwise.
   */
  public function validate(string $type): bool;

  /**
   * Gets orchestrator options for form select elements.
   *
   * Builds an options array suitable for use in form select, radios, or
   * checkboxes elements. Options are keyed by namespaced plugin ID with
   * human-readable labels as values.
   *
   * @param bool $includeDefault
   *   Whether to include a "Default (based on event)" option at the start.
   *   Defaults to FALSE.
   *
   * @return array<string, string>
   *   An array of orchestrator options keyed by plugin ID.
   */
  public function getFormOptions(bool $includeDefault = FALSE): array;

  /**
   * Checks if an orchestrator has a specific capability.
   *
   * Queries the plugin definition's declared capabilities without requiring
   * plugin instantiation. Capabilities are declared in the #[Orchestrator]
   * attribute.
   *
   * @param string $type
   *   The orchestrator type (namespaced ID).
   * @param string $capability
   *   The capability name (e.g., "synchronous_execution", "stateful").
   *
   * @return bool
   *   TRUE if the orchestrator has the capability, FALSE otherwise.
   */
  public function hasCapability(string $type, string $capability): bool;

  /**
   * Checks if an orchestrator type is StateGraph-based.
   *
   * Returns TRUE for orchestrators that declare the "stateful" capability.
   *
   * @param string $type
   *   The orchestrator type to check (namespaced ID).
   *
   * @return bool
   *   TRUE if the orchestrator is stateful, FALSE otherwise.
   */
  public function isStateGraph(string $type): bool;

  /**
   * Checks if an orchestrator type is synchronous (non-stateful).
   *
   * Returns TRUE for orchestrators that declare "synchronous_execution"
   * but not "stateful". This distinguishes plain synchronous orchestrators
   * from stateful ones like StateGraph which also execute synchronously.
   *
   * @param string $type
   *   The orchestrator type to check (namespaced ID).
   *
   * @return bool
   *   TRUE if the orchestrator is synchronous and non-stateful.
   */
  public function isSynchronous(string $type): bool;

}
