<?php

declare(strict_types=1);

namespace Drupal\flowdrop_workflow\DTO;

/**
 * A single executable capability a workflow requires.
 *
 * One distinct node type (keyed by metadata.node_type_id) maps to one
 * capability. The status tells an importer whether the capability is ready to
 * run, can be
 * provisioned by generating a node type from an installed plugin, or is
 * unavailable because the providing module is not installed.
 *
 * @internal
 *   This class is not part of the public API and may change without notice.
 */
final class NodeCapability {

  /**
   * The node type exists and the backing plugin is installed: ready to run.
   */
  public const AVAILABLE = 'available';

  /**
   * The plugin is installed but no node type exists yet; it can be generated.
   */
  public const GENERATABLE = 'generatable';

  /**
   * The backing plugin is not installed; the provider module must be added.
   */
  public const MISSING = 'missing';

  /**
   * Constructs a NodeCapability.
   *
   * @param string $status
   *   One of the status constants.
   * @param string $nodeTypeId
   *   The node type id (metadata.node_type_id), the runtime's resolution key.
   * @param string $pluginId
   *   The declared executor plugin id (module:plugin).
   * @param string $providerModule
   *   The module expected to provide the plugin (its namespace prefix).
   * @param string|null $reason
   *   Human-readable explanation, for missing capabilities.
   */
  public function __construct(
    private readonly string $status,
    private readonly string $nodeTypeId,
    private readonly string $pluginId,
    private readonly string $providerModule,
    private readonly ?string $reason = NULL,
  ) {}

  /**
   * Gets the status.
   *
   * @return string
   *   One of the status constants.
   */
  public function getStatus(): string {
    return $this->status;
  }

  /**
   * Gets the node type id.
   *
   * @return string
   *   The node type id.
   */
  public function getNodeTypeId(): string {
    return $this->nodeTypeId;
  }

  /**
   * Gets the executor plugin id.
   *
   * @return string
   *   The plugin id.
   */
  public function getPluginId(): string {
    return $this->pluginId;
  }

  /**
   * Gets the provider module.
   *
   * @return string
   *   The provider module machine name.
   */
  public function getProviderModule(): string {
    return $this->providerModule;
  }

  /**
   * Gets the reason for a missing capability.
   *
   * @return string|null
   *   The reason, or NULL.
   */
  public function getReason(): ?string {
    return $this->reason;
  }

  /**
   * Converts to an array representation.
   *
   * @return array{status: string, node_type_id: string, plugin_id: string, provider_module: string, reason: string|null}
   *   The array form, suitable for an API preflight response.
   */
  public function toArray(): array {
    return [
      'status' => $this->status,
      'node_type_id' => $this->nodeTypeId,
      'plugin_id' => $this->pluginId,
      'provider_module' => $this->providerModule,
      'reason' => $this->reason,
    ];
  }

}
