<?php

declare(strict_types=1);

namespace Drupal\flowdrop\Constants;

/**
 * Constants for reserved names in the FlowDrop system.
 *
 * These names are reserved for system functionality and cannot be used
 * by plugins for custom parameters or outputs. They are organized into
 * two groups:
 *
 * - Config keys: Reserved properties injected into configSchema by the
 *   API layer (NodesController). Plugins must not use these as regular
 *   parameter names unless implementing the corresponding feature.
 *
 * - Port names: Reserved port identifiers used by the orchestrator and
 *   the workflow editor for system-level ports.
 *
 * @see docs/development/reserved-names.md
 *
 * @api
 */
final class ReservedName {

  // --- Reserved config keys ---
  // These are intercepted by NodesController::deriveSchemas() and routed
  // to configSchema regardless of entity configuration.

  /**
   * Dynamic input port definitions config key.
   */
  public const DYNAMIC_INPUTS = 'dynamicInputs';

  /**
   * Dynamic output port definitions config key.
   */
  public const DYNAMIC_OUTPUTS = 'dynamicOutputs';

  /**
   * Gateway branch definitions config key.
   */
  public const BRANCHES = 'branches';

  /**
   * Per-instance title override config key.
   */
  public const INSTANCE_TITLE = 'instanceTitle';

  /**
   * Per-instance description override config key.
   */
  public const INSTANCE_DESCRIPTION = 'instanceDescription';

  /**
   * Per-instance visual type selection config key.
   */
  public const NODE_TYPE = 'nodeType';

  // --- Reserved port names ---
  // These are used by the orchestrator and workflow editor.

  /**
   * Unified input port (accepts all connectable params as JSON).
   */
  public const PORT_INPUT = 'input';

  /**
   * Unified output port (provides all exposed outputs as JSON).
   */
  public const PORT_OUTPUT = 'output';

  /**
   * Trigger port for flow control signals.
   */
  public const PORT_TRIGGER = 'trigger';

  /**
   * Gateway output indicating which branches are active.
   */
  public const ACTIVE_BRANCHES = 'active_branches';

  /**
   * Parameter names that bypass entity config and route to configSchema.
   *
   * Used by NodesController::deriveSchemas() to detect parameters that
   * should always appear in the config form, never as input ports,
   * regardless of entity-level connectable/configurable flags.
   *
   * @return array<int, string>
   *   Parameter names that are always routed to configSchema.
   */
  public static function configSchemaOnlyParams(): array {
    return [
      self::DYNAMIC_INPUTS,
      self::DYNAMIC_OUTPUTS,
      self::BRANCHES,
    ];
  }

  /**
   * Names that are forbidden for use as dynamic port names.
   *
   * Used by DynamicPortTrait::validatePortNames() to reject user-defined
   * port names that would collide with system functionality.
   *
   * @return array<int, string>
   *   Names that cannot be used for dynamic ports.
   */
  public static function forbiddenPortNames(): array {
    return [
      self::PORT_INPUT,
      self::PORT_OUTPUT,
      self::PORT_TRIGGER,
      self::ACTIVE_BRANCHES,
      self::BRANCHES,
      self::NODE_TYPE,
      self::INSTANCE_TITLE,
      self::INSTANCE_DESCRIPTION,
      self::DYNAMIC_INPUTS,
      self::DYNAMIC_OUTPUTS,
    ];
  }

}
