<?php

declare(strict_types=1);

namespace Drupal\flowdrop_runtime\Service\Storage;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\flowdrop_pipeline\Entity\FlowDropPipelineInterface;
use Drupal\flowdrop_pipeline\Entity\FlowDropPipelineRuntimeInterface;

/**
 * Drupal entity-based implementation of pipeline storage.
 *
 * This implementation wraps Drupal's EntityTypeManager to provide
 * persistent storage for pipelines using the flowdrop_pipeline entity type.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
class DrupalPipelineStorage implements PipelineStorageInterface {

  /**
   * The entity type manager.
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * Constructs a new DrupalPipelineStorage.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entityTypeManager) {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * {@inheritdoc}
   */
  public function create(array $data): FlowDropPipelineRuntimeInterface {
    $storage = $this->entityTypeManager->getStorage('flowdrop_pipeline');

    // Normalize workflow_id to target_id format if needed.
    if (isset($data['workflow_id']) && !is_array($data['workflow_id'])) {
      $data['workflow_id'] = ['target_id' => $data['workflow_id']];
    }

    // Encode input_data if it's an array.
    if (isset($data['input_data']) && is_array($data['input_data'])) {
      $data['input_data'] = json_encode($data['input_data']);
    }

    // Handle execution_context separately as it uses a setter.
    $executionContext = $data['execution_context'] ?? NULL;
    unset($data['execution_context']);

    /** @var \Drupal\flowdrop_pipeline\Entity\FlowDropPipelineInterface $pipeline */
    $pipeline = $storage->create($data);

    if ($executionContext !== NULL) {
      $pipeline->setExecutionContext($executionContext);
    }

    return $pipeline;
  }

  /**
   * {@inheritdoc}
   */
  public function load(string|int $id): ?FlowDropPipelineRuntimeInterface {
    $storage = $this->entityTypeManager->getStorage('flowdrop_pipeline');
    $pipeline = $storage->load($id);

    return $pipeline instanceof FlowDropPipelineInterface ? $pipeline : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function save(FlowDropPipelineRuntimeInterface $pipeline): void {
    assert($pipeline instanceof FlowDropPipelineInterface);
    $pipeline->save();
  }

  /**
   * {@inheritdoc}
   */
  public function delete(FlowDropPipelineRuntimeInterface $pipeline): void {
    assert($pipeline instanceof FlowDropPipelineInterface);
    $pipeline->delete();
  }

  /**
   * {@inheritdoc}
   */
  public function resetCache(?array $ids = NULL): void {
    $storage = $this->entityTypeManager->getStorage('flowdrop_pipeline');
    $storage->resetCache($ids);
  }

}
