<?php

namespace Drupal\acquia_contenthub_subscriber\EventSubscriber\ParseCdf;

use Acquia\ContentHubClient\CDF\CDFObjectInterface;
use Drupal\acquia_contenthub\AcquiaContentHubEvents;
use Drupal\acquia_contenthub\Event\ParseCdfEntityEvent;
use Drupal\Core\Serialization\Yaml;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Base class to update uuid with entity id inside config entity CDF.
 *
 * The corresponding base class for parsing operations in case of config
 * entities. For more details on the subject see the linked class.
 *
 * @see \Drupal\acquia_contenthub\AcquiaContentHubEvents::PARSE_CDF
 * @see \Drupal\acquia_contenthub_publisher\EventSubscriber\Cdf\ConvertEntityIdToUuidCreateCdfEntityBase
 *
 * @package Drupal\acquia_contenthub_subscriber\EventSubscriber\ParseCdf
 */
abstract class ConvertEntityUuidToIdParseCdfBase implements EventSubscriberInterface {

  /**
   * The event dispatcher.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
   */
  protected $dispatcher;

  /**
   * ConvertEntityUuidToIdParseCdfBase constructor.
   *
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
   *   The event dispatcher.
   */
  public function __construct(EventDispatcherInterface $dispatcher) {
    $this->dispatcher = $dispatcher;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    $events[AcquiaContentHubEvents::PARSE_CDF][] = ['onParseCdf', 101];
    return $events;
  }

  /**
   * Updates entity uuid with id.
   *
   * @param \Drupal\acquia_contenthub\Event\ParseCdfEntityEvent $event
   *   The create cdf entity event.
   */
  abstract public function replaceEntityUuidWithId(ParseCdfEntityEvent $event): void;

  /**
   * Replace entity uuid with entity id.
   *
   * @param \Drupal\acquia_contenthub\Event\ParseCdfEntityEvent $event
   *   The parse cdf entity event.
   *
   * @throws \Exception
   */
  public function onParseCdf(ParseCdfEntityEvent $event) {
    $cdf = $event->getCdf();
    if ($cdf->getType() !== 'drupal8_config_entity') {
      return;
    }
    $this->replaceEntityUuidWithId($event);
  }

  /**
   * Extracts decoded metadata from entity.
   *
   * @param \Acquia\ContentHubClient\CDF\CDFObjectInterface $cdf
   *   The CDF object.
   *
   * @return array
   *   Decoded metadata.
   */
  public function getDecodedMetadata(CDFObjectInterface $cdf): array {
    $metadata = $cdf->getMetadata();
    return (array) Yaml::decode(base64_decode($metadata['data']));
  }

  /**
   * Encodes and updates metadata.
   *
   * @param \Drupal\acquia_contenthub\Event\ParseCdfEntityEvent $event
   *   The create cdf entity event.
   * @param mixed $metadata_data
   *   Decoded metadata.
   */
  public function updateMetadata(ParseCdfEntityEvent $event, $metadata_data): void {
    $cdf = $event->getCdf();
    $metadata = $cdf->getMetadata();
    $metadata['data'] = base64_encode(Yaml::encode($metadata_data));
    $cdf->setMetadata($metadata);
  }

}
