<?php

namespace Drupal\acquia_contenthub_subscriber\EventSubscriber\ReplaceEntityUuidWithId;

use Drupal\acquia_contenthub_subscriber\ContentHubSubscriberEvents;
use Drupal\acquia_contenthub_subscriber\Event\ViewFilterPluginReplaceEntityUuidWithIdEvent;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Updates entity uuid with id for view filter plugins.
 *
 * @see \Drupal\acquia_contenthub_subscriber\ContentHubSubscriberEvents::REPLACE_ENTITY_UUID_WITH_ID
 * @see \Drupal\acquia_contenthub_publisher\EventSubscriber\ReplaceEntityIdWithUuid\ViewFilterPluginReplaceEntityIdWithUuidBase
 *   Corresponding base for serialization subscribers.
 *
 * @package \Drupal\acquia_contenthub_subscriber\Event\ReplaceEntityUuidWithIdEvent
 */
abstract class ViewFilterPluginReplaceEntityUuidWithIdBase implements EventSubscriberInterface {

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

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

  /**
   * ViewFilterPluginReplaceEntityUuidWithIdBase constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Psr\Log\LoggerInterface $logger_channel
   *   The acquia_contenthub_subscriber 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[ContentHubSubscriberEvents::REPLACE_ENTITY_UUID_WITH_ID][] =
      ['onReplaceEntityUuidWithId'];
    return $events;
  }

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

  /**
   * Updates entity uuid with id.
   *
   * @param \Drupal\acquia_contenthub_subscriber\Event\ViewFilterPluginReplaceEntityUuidWithIdEvent $event
   *   The ReplaceEntityUuidWithIdEvent object.
   *
   * @throws \Exception
   */
  public function onReplaceEntityUuidWithId(ViewFilterPluginReplaceEntityUuidWithIdEvent $event): void {
    $filter_data = $event->getFilterData();
    $updated_filter_data = $this->replaceEntityUuidWithIdForViewFilterPlugin($filter_data);
    if (!empty($updated_filter_data)) {
      $event->setFilterData($updated_filter_data);
      $event->stopPropagation();
    }
  }

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

}
