<?php

namespace Drupal\Tests\acquia_contenthub\Kernel\EventSubscriber\HandleWebhook;

use Drupal\acquia_contenthub\AcquiaContentHubEvents;
use Drupal\acquia_contenthub\Client\CdfMetricsManager;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\acquia_contenthub\Kernel\EventSubscriber\HandleWebhook\Traits\HandleWebhookEventTestTrait;
use Drupal\Tests\acquia_contenthub\Traits\DatabaseAssertionsTrait;
use Drupal\Tests\acquia_contenthub\Traits\QueueTestTrait;

/**
 * Base class for purge event tests.
 *
 * Contains common test cases.
 */
abstract class PurgeTestBase extends KernelTestBase {

  use DatabaseAssertionsTrait;
  use HandleWebhookEventTestTrait;
  use QueueTestTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'acquia_contenthub',
    'depcalc',
    'user',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->installEntitySchema('user');
    $manager = $this->prophesize(CdfMetricsManager::class);
    $this->container->set('acquia_contenthub.cdf_metrics_manager', $manager->reveal());
  }

  /**
   * Tests the event subscriber on negative cases.
   *
   * When the crud is not purge or the response is failed.
   *
   * @throws \Exception
   */
  public function testWhenCrudIsNotPurgeOrNotSuccessful(): void {
    $this->populateTrackingTableWithRandomData(10);
    $this->populateQueueTableWithRandomData(10, $this->getQueueName());

    $event = $this->newHandleWebhookEvent([
      'status' => 'failed',
      'crud' => 'purge',
      'initiator' => $this->generateUuid(),
    ]);
    $this->container->get('event_dispatcher')->dispatch($event, AcquiaContentHubEvents::HANDLE_WEBHOOK);

    $queued_items = $this->container->get('queue')
      ->get($this->getQueueName())
      ->numberOfItems();
    $this->assertNumberOfRows($this->getTrackingTableName(), 10);
    $this->assertEquals(10, $queued_items);

    $event = $this->newHandleWebhookEvent([
      'status' => 'successful',
      'crud' => 'update',
      'initiator' => $this->generateUuid(),
    ]);
    $this->container->get('event_dispatcher')->dispatch($event, AcquiaContentHubEvents::HANDLE_WEBHOOK);

    $queued_items = $this->container->get('queue')
      ->get($this->getQueueName())
      ->numberOfItems();
    $this->assertNumberOfRows($this->getTrackingTableName(), 10);
    $this->assertEquals(10, $queued_items);
  }

  /**
   * Tests if the Client CDF is being recreated on purge event.
   */
  public function testClientCdfGetsCreated(): void {
    // Indicator that the client have been recreated.
    $metrics_manager = $this->prophesize(CdfMetricsManager::class);
    $metrics_manager->sendClientCdfUpdates()->shouldBeCalledOnce();
    $this->container->set('acquia_contenthub.cdf_metrics_manager', $metrics_manager->reveal());
    $event = $this->newHandleWebhookEvent([
      'status' => 'successful',
      'crud' => 'purge',
    ]);
    $this->container->get('event_dispatcher')->dispatch($event, AcquiaContentHubEvents::HANDLE_WEBHOOK);
  }

  /**
   * Inserts dummy data into the tracking tables.
   *
   * @param int $number_of_rows
   *   The number of rows to insert.
   */
  abstract public function populateTrackingTableWithRandomData(int $number_of_rows): void;

  /**
   * Returns the applicable queue name.
   *
   * @return string
   *   The name of the queue.
   */
  abstract protected function getQueueName(): string;

  /**
   * Returns the applicable tracking table name.
   *
   * @return string
   *   The name of the tracking table.
   */
  abstract protected function getTrackingTableName(): string;

}
