<?php

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

use Acquia\Hmac\Key;
use Drupal\acquia_contenthub\Event\HandleWebhookEvent;
use Drupal\acquia_contenthub_subscriber\EventSubscriber\HandleWebhook\ImportUpdateAssets;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\acquia_contenthub\Kernel\Traits\AcquiaContentHubAdminSettingsTrait;
use Drupal\Tests\acquia_contenthub\Traits\QueueTestTrait;
use Drupal\Tests\acquia_contenthub\Unit\Helpers\LoggerMock;
use Symfony\Component\HttpFoundation\Request;

/**
 * @coversDefaultClass \Drupal\acquia_contenthub_subscriber\EventSubscriber\HandleWebhook\ImportUpdateAssets
 *
 * @group acquia_contenthub
 *
 * @package Drupal\Tests\acquia_contenthub\Kernel
 */
class ImportUpdateAssetsTest extends KernelTestBase {

  use AcquiaContentHubAdminSettingsTrait;
  use QueueTestTrait;

  /**
   * ImportUpdateAssets instance.
   *
   * @var \Drupal\acquia_contenthub_subscriber\EventSubscriber\HandleWebhook\ImportUpdateAssets
   */
  protected $importUpdateAssets;

  /**
   * Subscriber tracker.
   *
   * @var \Drupal\acquia_contenthub_subscriber\SubscriberTracker
   */
  protected $subTracker;

  /**
   * The logger channel mock.
   *
   * @var \Drupal\Tests\acquia_contenthub\Unit\Helpers\LoggerMock
   */
  protected $loggerChannel;

  /**
   * Symfony request.
   *
   * @var \Symfony\Component\HttpFoundation\Request
   */
  protected Request $request;

  /**
   * Hmac key.
   *
   * @var \Acquia\Hmac\Key
   */
  protected Key $key;

  /**
   * Modules to enable.
   *
   * @var array
   */
  protected static $modules = [
    'field',
    'filter',
    'depcalc',
    'acquia_contenthub',
    'acquia_contenthub_subscriber',
    'acquia_contenthub_server_test',
    'acquia_contenthub_test',
    'system',
    'user',
    'node',
  ];

  /**
   * {@inheritDoc}
   */
  public function setUp(): void {
    parent::setup();

    $this->installSchema('acquia_contenthub_subscriber', 'acquia_contenthub_subscriber_import_tracking');

    $this->createAcquiaContentHubAdminSettings();
    $this->loggerChannel = new LoggerMock();
    $this->subTracker = $this->container->get('acquia_contenthub_subscriber.tracker');
    $ach_configurations = $this->container->get('acquia_contenthub.configuration');
    $queue_factory = $this->container->get('queue');
    $cdf_metrics_manager = $this->container->get('acquia_contenthub.cdf_metrics_manager');
    $queue_inspector = $this->container->get('acquia_contenthub_subscriber.import_queue_inspector');
    $interest_list_storage = $this->container->get('acquia_contenthub.interest_list_storage');

    $this->importUpdateAssets = new ImportUpdateAssets(
      $queue_factory,
      $this->subTracker,
      $this->loggerChannel,
      $ach_configurations,
      $cdf_metrics_manager,
      $queue_inspector,
      $interest_list_storage
    );
    $this->request = Request::createFromGlobals();
    $this->key = new Key('id', 'secret');
    $this->ensureQueueTableExists();
  }

  /**
   * @covers ::onHandleWebhook
   *
   * @throws \Exception
   */
  public function testOnHandleWebhook() {
    $uuid = '00000000-0003-460b-ac74-b6bed08b4441';
    $this->subTracker->queue($uuid);

    $payload = [
      'status' => 'successful',
      'crud' => 'update',
      'assets' => [
        [
          'uuid' => $uuid,
          'type' => 'drupal8_content_entity',
        ],
      ],
      'initiator' => $uuid,
    ];

    $client_factory = $this->container->get('acquia_contenthub.client.factory');

    $event = new HandleWebhookEvent($this->request, $payload, $this->key, $client_factory->getClient());

    $this->assertEmpty($this->loggerChannel->getLogMessages());

    $this->importUpdateAssets->onHandleWebhook($event);
    $log_messages = $this->loggerChannel->getLogMessages();
    $this->assertNotEmpty($log_messages);

    // Assert there are info in log messages.
    $this->assertNotEmpty($log_messages[RfcLogLevel::INFO]);

    // Assert first message in info.
    $this->assertContains(
      "Attempting to add entity with UUID $uuid to the import queue.",
      $log_messages[RfcLogLevel::INFO]
    );
    $this->assertContains(
      sprintf('Entities with UUIDs %s added to the import queue and to the tracking table.', print_r([$uuid], TRUE)),
      $log_messages[RfcLogLevel::INFO]
    );
  }

  /**
   * Tests onHandleWebhook with AutoUpdateDisabled status.
   */
  public function testOnHandleWebhookWithAutoUpdateDisabledEntityStatus() {
    $uuid = '00000000-0003-460b-ac74-b6bed08b4441';
    $this->subTracker->queue($uuid);
    $this->subTracker->setStatusByUuid($uuid, $this->subTracker::AUTO_UPDATE_DISABLED);

    $payload = [
      'status' => 'successful',
      'crud' => 'update',
      'assets' => [
        [
          'uuid' => $uuid,
          'type' => 'drupal8_content_entity',
        ],
      ],
      'initiator' => $uuid,
    ];

    $client_factory = $this->container->get('acquia_contenthub.client.factory');

    $event = new HandleWebhookEvent($this->request, $payload, $this->key, $client_factory->getClient());

    $this->assertEmpty($this->loggerChannel->getLogMessages());

    $this->importUpdateAssets->onHandleWebhook($event);
    $log_messages = $this->loggerChannel->getLogMessages();
    $this->assertNotEmpty($log_messages);

    // Assert there are info in log messages.
    $this->assertEquals(
      'Entity with UUID 00000000-0003-460b-ac74-b6bed08b4441 was not added to the import queue because it has auto update disabled.',
      $log_messages[RfcLogLevel::INFO][0]
    );
  }

  /**
   * Testing webhook handling when reason attribute is available in payload.
   */
  public function testWebhookHandlingWithReasonAttribute(): void {
    $entity_uuid = '00000000-0003-460b-ac74-b6bed08b4441';
    $this->subTracker->queue($entity_uuid);
    $filter_uuid = '10000000-0003-460b-ac74-b6bed08b4441';

    $payload = [
      'status' => 'successful',
      'crud' => 'update',
      'assets' => [
        [
          'uuid' => $entity_uuid,
          'type' => 'drupal8_content_entity',
        ],
      ],
      'initiator' => 'some-initiator',
      'reason' => $filter_uuid,
    ];

    $client_factory = $this->container->get('acquia_contenthub.client.factory');

    $event = new HandleWebhookEvent($this->request, $payload, $this->key, $client_factory->getClient());

    $this->importUpdateAssets->onHandleWebhook($event);
    $log_messages = $this->loggerChannel->getLogMessages();
    $this->assertNotEmpty($log_messages);

    $this->assertContains(
      sprintf('Entities with UUIDs %s added to the import queue and to the tracking table. Reason: %s',
        print_r([$entity_uuid], TRUE),
        $filter_uuid,
      ),
      $log_messages[RfcLogLevel::INFO]
    );
  }

}
