<?php

namespace Drupal\acquia_contenthub_subscriber\EventSubscriber\EntityDataTamper;

use Drupal\acquia_contenthub\AcquiaContentHubEvents;
use Drupal\acquia_contenthub\Event\EntityDataTamperEvent;
use Drupal\acquia_contenthub\Libs\InterestList\InterestListStorageInterface;
use Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface;
use Drupal\acquia_contenthub_subscriber\SubscriberTracker;
use Drupal\depcalc\DependentEntityWrapper;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Place entities that are marked disabled for syndication.
 *
 * Into the dependency stack.
 */
class DisabledEntity implements EventSubscriberInterface {

  /**
   * The subscriber tracker.
   *
   * @var \Drupal\acquia_contenthub_subscriber\SubscriberTracker
   */
  protected SubscriberTracker $tracker;

  /**
   * The interest list storage.
   *
   * @var \Drupal\acquia_contenthub\Libs\InterestList\InterestListStorageInterface
   */
  protected InterestListStorageInterface $interestListStorage;

  /**
   * CH configurations.
   *
   * @var \Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface
   */
  protected ContentHubConfigurationInterface $achConfigurations;

  /**
   * DisabledEntity constructor.
   *
   * @param \Drupal\acquia_contenthub_subscriber\SubscriberTracker $tracker
   *   Subscriber tracker.
   * @param \Drupal\acquia_contenthub\Libs\InterestList\InterestListStorageInterface $interest_storage
   *   The interest list storage.
   * @param \Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface $ach_configurations
   *   CH Configurations.
   *
   * @throws \Exception
   */
  public function __construct(SubscriberTracker $tracker, InterestListStorageInterface $interest_storage, ContentHubConfigurationInterface $ach_configurations) {
    $this->tracker = $tracker;
    $this->interestListStorage = $interest_storage;
    $this->achConfigurations = $ach_configurations;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    $events[AcquiaContentHubEvents::ENTITY_DATA_TAMPER][] = [
      'onDataTamper',
      100,
    ];

    return $events;
  }

  /**
   * Tamper with CDF data before its imported.
   *
   * @param \Drupal\acquia_contenthub\Event\EntityDataTamperEvent $event
   *   The data tamper event.
   *
   * @throws \Exception
   */
  public function onDataTamper(EntityDataTamperEvent $event) {
    $cdf = $event->getCdf();
    $cdf_entities = $cdf->getEntities();
    $uuids = array_keys($cdf_entities);
    $disabled_uuids = $this->getDisabledEntities($uuids);
    foreach ($disabled_uuids as $uuid) {
      if ($this->tracker->getStatusByUuid($uuid) !== SubscriberTracker::AUTO_UPDATE_DISABLED) {
        continue;
      }
      $entity = $this->tracker->getEntityByRemoteIdAndHash($uuid);
      if ($entity) {
        $wrapper = new DependentEntityWrapper($entity);
        $wrapper->setRemoteUuid($uuid);
        $event->getStack()->addDependency($wrapper, FALSE);
      }
    }
  }

  /**
   * Fetches the disabled entities from interest list storage.
   *
   * @param array $uuids
   *   Uuids of the CDF entities.
   *
   * @return array
   *   List of uuids that are disabled.
   *
   * @throws \Exception
   */
  public function getDisabledEntities(array $uuids): array {
    $settings = $this->achConfigurations->getSettings();
    $webhook_uuid = $settings->getWebhook('uuid');
    $disabled_entities = $this->interestListStorage->getInterestList(
      $webhook_uuid,
      'subscriber',
      ['uuids' => $uuids, 'disable_syndication' => TRUE]);
    // Marking entities as disabled in import tracker.
    if (!empty($disabled_entities)) {
      $this->tracker->setStatusByUuids(array_keys($disabled_entities), SubscriberTracker::AUTO_UPDATE_DISABLED);
    }
    return array_keys($disabled_entities);
  }

}
