<?php

namespace Drupal\acquia_contenthub_publisher\EventSubscriber\ReplaceEntityIdWithUuid;

use Drupal\acquia_contenthub_publisher\ContentHubPublisherEvents;
use Drupal\acquia_contenthub_publisher\Event\ViewFilterPluginReplaceEntityIdWithUuidEvent;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Updates entity id with uuid for view filter plugins.
 *
 * @see \Drupal\acquia_contenthub_publisher\ContentHubPublisherEvents::REPLACE_ENTITY_ID_WITH_UUID
 * @see \Drupal\acquia_contenthub_subscriber\EventSubscriber\ReplaceEntityUuidWithId\ViewFilterPluginReplaceEntityUuidWithIdBase
 *   Corresponding base for unserialization subscribers.
 *
 * @package \Drupal\acquia_contenthub_publisher\Event\ReplaceEntityIdWithUuidEvent
 */
abstract class ViewFilterPluginReplaceEntityIdWithUuidBase implements EventSubscriberInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The acquia_contenthub_publisher logger channel.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $loggerChannel;

  /**
   * ViewFilterPluginReplaceEntityIdWithUuidBase constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Psr\Log\LoggerInterface $logger_channel
   *   The acquia_contenthub_publisher logger channel.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, LoggerInterface $logger_channel) {
    $this->entityTypeManager = $entity_type_manager;
    $this->loggerChannel = $logger_channel;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    $events[ContentHubPublisherEvents::REPLACE_ENTITY_ID_WITH_UUID][] =
      ['onReplaceEntityIdWithUuid'];
    return $events;
  }

  /**
   * Replaces entity id with uuid for plugins.
   *
   * @param array $filter_data
   *   The filter data.
   *
   * @return array
   *   Updated filter data.
   *
   * @throws \Exception
   */
  abstract public function replaceEntityIdWithUuidForViewFilterPlugin(array $filter_data): array;

  /**
   * Updates entity id with uuid for plugins.
   *
   * @param \Drupal\acquia_contenthub_publisher\Event\ViewFilterPluginReplaceEntityIdWithUuidEvent $event
   *   The ReplaceEntityIdWithUuidEvent object.
   *
   * @throws \Exception
   */
  public function onReplaceEntityIdWithUuid(ViewFilterPluginReplaceEntityIdWithUuidEvent $event): void {
    $filter_data = $event->getFilterData();
    $updated_filter_data = $this->replaceEntityIdWithUuidForViewFilterPlugin($filter_data);
    if (!empty($updated_filter_data)) {
      $event->setFilterData($updated_filter_data);
      $event->stopPropagation();
    }
  }

  /**
   * Logs missing entities while creating CDF.
   *
   * @param string $entity_type
   *   The entity type.
   * @param string $entity_id
   *   The entity id.
   * @param string $plugin_id
   *   The plugin id.
   */
  public function logMissingEntity(string $entity_type, string $entity_id, string $plugin_id): void {
    $this->loggerChannel->warning(
      'Entity of type: {type} and id: {id} not found while serialization of {plugin_id} view filter plugin.',
      [
        'type' => $entity_type,
        'id' => $entity_id,
        'plugin_id' => $plugin_id,
      ]
    );
  }

}
