<?php

namespace Drupal\Tests\acquia_contenthub_subscriber\Kernel\EventSubscriber\EntityDataTamper;

use Acquia\ContentHubClient\CDF\CDFObject;
use Acquia\ContentHubClient\CDFDocument;
use Acquia\ContentHubClient\Settings;
use Drupal\acquia_contenthub\Event\EntityDataTamperEvent;
use Drupal\acquia_contenthub\Libs\InterestList\InterestListStorageInterface;
use Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface;
use Drupal\acquia_contenthub_subscriber\EventSubscriber\EntityDataTamper\DisabledEntity;
use Drupal\acquia_contenthub_subscriber\SubscriberTracker;
use Drupal\Core\Entity\EntityInterface;
use Drupal\depcalc\DependencyStack;
use Drupal\depcalc\DependentEntityWrapper;
use Drupal\KernelTests\KernelTestBase;
use Prophecy\Argument;

/**
 * Tests DisabledEntity event subscriber.
 *
 * @coversDefaultClass \Drupal\acquia_contenthub_subscriber\EventSubscriber\EntityDataTamper\DisabledEntity
 *
 * @package acquia_contenthub_subscriber
 */
class DisabledEntityTest extends KernelTestBase {

  /**
   * Webhook uuid.
   */
  protected const WEBHOOK_UUID = 'webhook-uuid';

  /**
   * Entity uuid.
   */
  protected const ENTITY_UUID = '00000000-0000-0000-0000-000000000001';

  /**
   * Entity uuid 2.
   */
  protected const ENTITY_UUID_2 = '00000000-0000-0000-0000-000000000002';

  /**
   * Subscriber tracker mock.
   *
   * @var \Drupal\acquia_contenthub_subscriber\SubscriberTracker|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $subscriberTracker;

  /**
   * SUT.
   *
   * @var \Drupal\acquia_contenthub_subscriber\EventSubscriber\EntityDataTamper\DisabledEntity
   */
  protected DisabledEntity $sut;

  /**
   * Interest list storage mock.
   *
   * @var \Drupal\acquia_contenthub\Libs\InterestList\InterestListStorageInterface|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $interestListStorage;

  /**
   * Disabled entities.
   *
   * @var array
   */
  public static array $disabledEntities = [];

  /**
   * {@inheritDoc}
   *
   * @throws \Exception
   */
  public function setUp(): void {
    parent::setUp();
    $this->subscriberTracker = $this->prophesize(SubscriberTracker::class);
    $this->interestListStorage = $this->prophesize(InterestListStorageInterface::class);
    $this->interestListStorage->resetCache();
    $achConfigurations = $this->prophesize(ContentHubConfigurationInterface::class);
    $settings = $this->prophesize(Settings::class);
    $settings->getWebhook('uuid')->willReturn('webhook-uuid');
    $achConfigurations->getSettings()->willReturn($settings->reveal());
    $this->sut = new DisabledEntity($this->subscriberTracker->reveal(), $this->interestListStorage->reveal(), $achConfigurations->reveal());
  }

  /**
   * @covers ::onDataTamper
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function testOnDataTamper(): void {
    $cdf_document = $this->prophesize(CDFDocument::class);
    $cdf_object1 = new CDFObject('', self::ENTITY_UUID, '', '', '', []);
    $cdf_object2 = new CDFObject('', self::ENTITY_UUID_2, '', '', '', []);
    $cdf_document
      ->getEntities()
      ->shouldBeCalled()
      ->willReturn([$cdf_object1, $cdf_object2]);
    $this->interestListStorage->getInterestList(Argument::any(), Argument::any(), Argument::any())->willReturn([self::ENTITY_UUID => self::ENTITY_UUID]);
    $stack = $this->prophesize(DependencyStack::class);
    $stack->addDependency(Argument::type(DependentEntityWrapper::class), Argument::type('bool'))
      ->shouldBeCalledOnce()
      ->will(function ($args) {
        /** @var \Drupal\depcalc\DependentEntityWrapper $wrapper */
        $wrapper = $args[0];
        self::$disabledEntities[] = $wrapper->getUuid();
      });
    $event = new EntityDataTamperEvent($cdf_document->reveal(), $stack->reveal());
    $entity = $this->prophesize(EntityInterface::class);
    $entity
      ->uuid()
      ->shouldBeCalled()
      ->willReturn(self::ENTITY_UUID);
    $entity->getEntityTypeId()
      ->shouldBeCalled()
      ->willReturn('');
    $entity->id()
      ->shouldBeCalled()
      ->willReturn('');
    $entity->toArray()
      ->shouldBeCalled()
      ->willReturn([]);
    $this->subscriberTracker
      ->setStatusByUuids([self::ENTITY_UUID],
        "auto_update_disabled")
      ->shouldBeCalled();
    $this->subscriberTracker
      ->getStatusByUuid(self::ENTITY_UUID)
      ->willReturn(SubscriberTracker::AUTO_UPDATE_DISABLED);
    $this->subscriberTracker
      ->getEntityByRemoteIdAndHash(self::ENTITY_UUID)
      ->shouldBeCalled()
      ->willReturn($entity->reveal());
    $this->subscriberTracker
      ->getEntityByRemoteIdAndHash(self::ENTITY_UUID_2)
      ->shouldNotBeCalled();
    $this->sut->onDataTamper($event);
    $this->assertContains(self::ENTITY_UUID, self::$disabledEntities);
    $this->assertNotContains(self::ENTITY_UUID_2, self::$disabledEntities);
  }

}
