<?php

declare(strict_types=1);

namespace Drupal\flowdrop_runtime\DTO\Compiler;

/**
 * Represents a node's mapping to a processor plugin.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
class NodeMapping {

  public function __construct(
    private readonly string $nodeId,
    private readonly string $processorId,
    private readonly array $config,
    private readonly array $metadata,
    private readonly string $nodeTypeId = '',
  ) {}

  /**
   * Get the node ID.
   *
   * @return string
   *   The node ID.
   */
  public function getNodeId(): string {
    return $this->nodeId;
  }

  /**
   * Get the processor plugin ID.
   *
   * @return string
   *   The processor plugin ID.
   */
  public function getProcessorId(): string {
    return $this->processorId;
  }

  /**
   * Get the node-type config-entity ID.
   *
   * Unlike {@see getProcessorId()} — which returns the executor plugin ID,
   * always colon-separated (module/derivative prefix) — this returns the
   * `flowdrop_node_type` config entity ID (flat, underscore form) carried in
   * the node's `metadata.node_type_id` anchor. It is the ID the runtime expects
   * when loading a node type from storage (NodeRuntimeService::executeNode()).
   *
   * Returns '' when the node carries no anchor. It deliberately does NOT fall
   * back to the processor ID: entity IDs are never colon-namespaced and plugin
   * IDs always are, so the two identifier spaces never overlap — substituting
   * the plugin ID here could only ever yield a value that fails the entity
   * load, silently reproducing the very confusion this accessor exists to
   * prevent. A missing anchor on an executable node is a real defect and must
   * surface as one, not be papered over.
   *
   * @return string
   *   The node-type config-entity ID, or '' when the node carries no anchor.
   */
  public function getNodeTypeId(): string {
    return $this->nodeTypeId;
  }

  /**
   * Get the node configuration.
   *
   * @return array
   *   The node configuration.
   */
  public function getConfig(): array {
    return $this->config;
  }

  /**
   * Get the metadata.
   *
   * @return array
   *   The metadata.
   */
  public function getMetadata(): array {
    return $this->metadata;
  }

  /**
   * Get the node label.
   *
   * @return string
   *   The node label.
   */
  public function getLabel(): string {
    return $this->metadata['label'] ?? $this->nodeId;
  }

  /**
   * Get the node description.
   *
   * @return string
   *   The node description.
   */
  public function getDescription(): string {
    return $this->metadata['description'] ?? '';
  }

  /**
   * Convert to array for serialization.
   *
   * @return array
   *   Array representation of the node mapping.
   */
  public function toArray(): array {
    return [
      'node_id' => $this->nodeId,
      'processor_id' => $this->processorId,
      'node_type_id' => $this->getNodeTypeId(),
      'config' => $this->config,
      'metadata' => $this->metadata,
    ];
  }

}
