<?php

namespace Drupal\Tests\acquia_contenthub_subscriber\Unit\EventSubscriber\ReplaceEntityUuidWithId;

use Drupal\acquia_contenthub_subscriber\Event\ViewFilterPluginReplaceEntityUuidWithIdEvent;
use Drupal\acquia_contenthub_subscriber\EventSubscriber\ReplaceEntityUuidWithId\NumericViewFilterPlugin;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\Tests\acquia_contenthub\Traits\CommonRandomGenerator;
use Drupal\Tests\acquia_contenthub\Unit\Helpers\LoggerMock;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Tests to replace entity uuid with id for NumericViewFilterPlugin.
 *
 * @group acquia_contenthub_subscriber
 *
 * @package Drupal\Tests\acquia_contenthub_subscriber\Unit\EventSubscriber\ReplaceEntityUuidWithId
 *
 * @coversDefaultClass \Drupal\acquia_contenthub_subscriber\EventSubscriber\ReplaceEntityUuidWithId\NumericViewFilterPlugin
 */
class NumericViewFilterPluginTest extends UnitTestCase {

  use CommonRandomGenerator;

  /**
   * Test replacing entity uuid with id for NumericViewFilterPlugin.
   *
   * Field type: entity_reference.
   *
   * @covers ::replaceEntityUuidWithIdForViewFilterPlugin
   */
  public function testNumericViewFilterPluginEntityReferenceFieldType() {
    $uuid1 = $this->generateUuid();
    $uuid2 = $this->generateUuid();
    $field_definition = $this->prophesize(FieldStorageConfigInterface::class);
    $field_definition->getType()->willReturn('entity_reference');
    $field_definition->getSettings()->willReturn([
      'target_type' => 'node',
    ]);
    $entity = $this->prophesize(EntityInterface::class);
    $entity->id()->willReturn(20);
    $entity_storage = $this->prophesize(EntityStorageInterface::class);
    $entity_storage->load('node.field_basic_content_type')->willReturn($field_definition->reveal());
    $entity_storage->loadByProperties(['uuid' => [$uuid1]])->willReturn([$entity->reveal()]);
    $entity_storage->loadByProperties(['uuid' => [$uuid2]])->willReturn(NULL);
    $entity_storage->loadByProperties(['uuid' => ['']])->willReturn(NULL);
    $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
    $entity_type_manager->getStorage('field_storage_config')->willReturn($entity_storage);
    $entity_type_manager->getStorage('node')->willReturn($entity_storage);

    $container = $this->prophesize(ContainerInterface::class);
    $container
      ->get('entity_type.manager')
      ->willReturn($entity_type_manager->reveal());
    \Drupal::setContainer($container->reveal());

    $filter_data = [
      'table' => 'node__field_basic_content_type',
      'plugin_id' => 'numeric',
      'value' => [
        'min' => '',
        'max' => $uuid2,
        'value' => $uuid1,
      ],
    ];
    $plugin_id = 'numeric';

    $event = new ViewFilterPluginReplaceEntityUuidWithIdEvent($filter_data, $plugin_id);
    $logger = new LoggerMock();
    $event_subscriber = new NumericViewFilterPlugin($entity_type_manager->reveal(), $logger);
    $event_subscriber->onReplaceEntityUuidWithId($event);

    $expected_filter_data = [
      'table' => 'node__field_basic_content_type',
      'plugin_id' => 'numeric',
      'value' => [
        'min' => '',
        'max' => $uuid2,
        'value' => 20,
      ],
    ];
    $this->assertSame($expected_filter_data, $event->getFilterData());
    $log_messages = $logger->getLogMessages();
    $this->assertNotEmpty($log_messages);
    $this->assertEquals(
      'Entity of type: node and uuid: ' . $uuid2 . ' not found while unserialization of numeric view filter plugin.',
      $log_messages[RfcLogLevel::WARNING][0]
    );
  }

  /**
   * Test replacing entity uuid with id for NumericViewFilterPlugin.
   *
   * Field type: integer.
   */
  public function testNumericViewFilterPluginIntegerFieldType() {
    $field_definition = $this->prophesize(FieldStorageConfigInterface::class);
    $field_definition->getType()->willReturn('integer');
    $entity_storage = $this->prophesize(EntityStorageInterface::class);
    $entity_storage->load('node.field_age')->willReturn($field_definition->reveal());
    $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
    $entity_type_manager->getStorage('field_storage_config')->willReturn($entity_storage);
    $container = $this->prophesize(ContainerInterface::class);
    $container
      ->get('entity_type.manager')
      ->willReturn($entity_type_manager->reveal());
    \Drupal::setContainer($container->reveal());

    $filter_data = [
      'table' => 'node__field_age',
      'plugin_id' => 'numeric',
      'value' => [
        'min' => '',
        'max' => '',
        'value' => 20,
      ],
    ];
    $plugin_id = 'numeric';

    $event = new ViewFilterPluginReplaceEntityUuidWithIdEvent($filter_data, $plugin_id);
    $event_subscriber = new NumericViewFilterPlugin($entity_type_manager->reveal(), new LoggerMock());
    $event_subscriber->onReplaceEntityUuidWithId($event);
    $this->assertSame($filter_data, $event->getFilterData());
  }

}
