<?php

namespace Drupal\acquia_contenthub;

use Drupal\Core\Database\Connection;
use Drupal\Core\Queue\QueueFactory;

/**
 * Provides items from queue data.
 */
abstract class AcquiaContentHubQueueInspectorBase implements QueueInspectorInterface {

  /**
   * The queue factory.
   *
   * @var \Drupal\Core\Queue\QueueFactory
   */
  protected $queueFactory;

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * The AcquiaContentHubQueueInspectorBase constructor.
   *
   * @param \Drupal\Core\Queue\QueueFactory $queue_factory
   *   The queue factory.
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   */
  public function __construct(QueueFactory $queue_factory, Connection $database) {
    $this->queueFactory = $queue_factory;
    $this->database = $database;
  }

  /**
   * {@inheritdoc}
   */
  public function getQueueData(string $type = '', string $uuid = '', int $limit = self::NO_LIMIT): array {
    $queue_table_data = $this->getQueueTableData($limit);
    return $this->getFormattedQueueData($queue_table_data, $type, $uuid);
  }

  /**
   * Provides queue table data for specific queue name.
   *
   * @param int $limit
   *   Limit of the queue items to be provided.
   *
   * @return array
   *   Queue table data.
   */
  protected function getQueueTableData(int $limit): array {
    $query = $this->database->select('queue', 'q')
      ->fields('q', ['data'])
      ->condition('name', $this->getQueueName(), '=');

    if ($limit >= 0) {
      $query->range(0, $limit);
    }
    return $query->execute()->fetchAll();
  }

  /**
   * Provides key-value paired data of queue.
   *
   * @param array $queue_table_data
   *   Array of serialised queue table data.
   * @param string $type
   *   The entity type.
   * @param string $uuid
   *   The entity uuid.
   *
   * @return array
   *   Key-value associative queue data:
   *     [
   *       [
   *         'type' => 'block',
   *         'uuid' => '34726dde-ad4c-4ec0-9080-0c7462e37e0d'
   *       ],
   *     ]
   */
  protected function getFormattedQueueData(array $queue_table_data, string $type, string $uuid): array {
    $data = [];
    foreach ($queue_table_data as $row) {
      $unserialised_row_data = unserialize($row->data, ['allowed_classes' => [\stdClass::class]]);
      $row_data = json_decode(json_encode($unserialised_row_data), TRUE);
      if ($this->isMatchingData($row_data, $type, $uuid)) {
        $data[] = $row_data;
      }
    }
    return $data;
  }

  /**
   * Checks if entity type of entity uuid matches for provided data.
   *
   * @param array $data
   *   Key-value paired data.
   * @param string $type
   *   The entity type.
   * @param string $uuid
   *   The entity uuid.
   *
   * @return bool
   *   True, if entity type or uuid matches.
   */
  protected function isMatchingData(array $data, string $type, string $uuid): bool {
    if (!empty($type) && array_key_exists('type', $data) && $data['type'] !== $type) {
      return FALSE;
    }
    if (!empty($uuid) && array_key_exists('uuid', $data) && $data['uuid'] !== $uuid) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  abstract public function getQueueName(): string;

}
