<?php

namespace Drupal\Tests\acquia_contenthub_translations\Kernel;

use Acquia\ContentHubClient\CDFDocument;
use Acquia\ContentHubClient\ContentHubClient;
use Acquia\ContentHubClient\Settings;
use Drupal\acquia_contenthub\Client\ClientFactory;
use Drupal\acquia_contenthub\Libs\ServiceQueue\QueueItem;
use Drupal\acquia_contenthub\Libs\ServiceQueue\ServiceQueueEntityActions;
use Drupal\acquia_contenthub_subscriber\SubscriberTracker;
use Drupal\acquia_contenthub_translations\Form\ContentHubTranslationsSettingsForm;
use Drupal\acquia_contenthub_translations\Libs\PullSyndication\TranslatableEntityUpsertAction;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\acquia_contenthub\Unit\Helpers\LoggerMock;
use Prophecy\Argument;
use Psr\Http\Message\ResponseInterface;

/**
 * Tests translatable entities for import in pull syndication.
 *
 * @coversDefaultClass \Drupal\acquia_contenthub_translations\Libs\PullSyndication\TranslatableEntityUpsertAction
 *
 * @group acquia_contenthub_translations
 *
 * @requires module depcalc
 *
 * @package Drupal\Tests\acquia_contenthub_translations\Kernel
 */
class TranslatableEntityUpsertActionTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'acquia_contenthub',
    'acquia_contenthub_translations',
    'acquia_contenthub_subscriber',
    'depcalc',
    'system',
    'user',
  ];
  /**
   * Content Hub translation config.
   *
   * @var \Drupal\Core\Config\Config
   */
  protected $translationConfig;

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

  /**
   * Content hub client mock.
   *
   * @var \Acquia\ContentHubClient\ContentHubClient|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $client;

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

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

  /**
   * {@inheritDoc}
   */
  public function setUp(): void {
    parent::setUp();
    $this->installSchema('acquia_contenthub_subscriber', SubscriberTracker::IMPORT_TRACKING_TABLE);
    $this->translationConfig = $this->config(ContentHubTranslationsSettingsForm::CONFIG);
    $this->translationConfig->set('selective_language_import', TRUE)->save();
    $this->tracker = $this->container->get('acquia_contenthub_subscriber.tracker');
    $this->client = $this->prophesize(ContentHubClient::class);
    $webhook = [
      'uuid' => 'w-uuid',
    ];
    $settings = new Settings('foo', '89ea74ad-930a-46a3-9c4d-402d381e45d4', 'apikey', 'secretkey', 'https://example.com', '', $webhook);
    $this->client
      ->getSettings()
      ->willReturn($settings);
    $this->client
      ->getInterestList('w-uuid', 'subscriber', Argument::any())
      ->willReturn([]);
    $this->client
      ->getEntities(Argument::any())
      ->willReturn(new CDFDocument());
    $response = $this->prophesize(ResponseInterface::class);
    $this->client
      ->updateInterestListBySiteRole(Argument::any(), Argument::any(), Argument::any())
      ->willReturn($response->reveal());

    $this->client
      ->deleteInterest(Argument::any(), Argument::any())
      ->willReturn($response->reveal());

    $client_factory = $this->prophesize(ClientFactory::class);
    $client_factory->getClient()->willReturn($this->client->reveal());
    $this->container->set('acquia_contenthub.client.factory', $client_factory->reveal());

    $this->logger = new LoggerMock();
    $this->subscriberLogger = new LoggerMock();
  }

  /**
   * Instantiates translatable asset importer.
   *
   * @return \Drupal\acquia_contenthub_translations\Libs\PullSyndication\TranslatableEntityUpsertAction
   *   Assert importer object.
   *
   * @throws \Exception
   */
  protected function getAssertImporter(): TranslatableEntityUpsertAction {
    return new TranslatableEntityUpsertAction(
      $this->tracker,
      $this->container->get('acquia_contenthub.configuration'),
      $this->container->get('acquia_contenthub.interest_list_storage'),
      $this->container->get('acquia_contenthub_subscriber.ch_logger'),
      $this->container->get('acquia_contenthub_subscriber.entity_import'),
      $this->container->get('acquia_contenthub.client.factory'),
      $this->container->get('config.factory'),
      $this->logger,
      $this->container->get('acquia_contenthub_translations.translatable_entity_filter'),
    );
  }

  /**
   * Tests canHandle() method for different actions.
   */
  public function testCanHandleWithInvalidAction(): void {
    $importer = $this->getAssertImporter();

    $queue_item = new QueueItem(
      'item-id',
      '89ea74ad-930a-46a3-9c4d-402d381e45d3',
      'client-uuid',
      'visible',
      ['action' => ServiceQueueEntityActions::DELETE, 'type' => 'drupal8_content_entity'],
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s')
    );
    $this->assertFalse($importer->canHandle($queue_item));

    $queue_item_create = new QueueItem(
      'item-id',
      '89ea74ad-930a-46a3-9c4d-402d381e45d3',
      'client-uuid',
      'visible',
      ['action' => ServiceQueueEntityActions::CREATE, 'type' => 'drupal8_content_entity'],
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s')
    );
    $this->assertTrue($importer->canHandle($queue_item_create));

    $queue_item_update = new QueueItem(
      'item-id',
      '89ea74ad-930a-46a3-9c4d-402d381e45d3',
      'client-uuid',
      'visible',
      ['action' => ServiceQueueEntityActions::UPDATE, 'type' => 'drupal8_content_entity'],
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s')
    );

    $this->assertTrue($importer->canHandle($queue_item_update));
  }

  /**
   * Tests execute() logs and returns if initiator is the same as client.
   */
  public function testExecuteInitiatorIsClient(): void {
    $importer = $this->getAssertImporter();

    $queue_item = new QueueItem(
      'item-id',
      '89ea74ad-930a-46a3-9c4d-402d381e45d3',
      'different-client-uuid',
      'visible',
      [
        'action' => ServiceQueueEntityActions::UPDATE,
        'type' => 'drupal8_content_entity',
        'initiator' => '89ea74ad-930a-46a3-9c4d-402d381e45d4',
      ],
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s'),
      date('Y-m-d H:i:s')
    );

    $importer->execute([$queue_item]);
    $this->assertNotEmpty($this->logger->getInfoMessages());
    $this->assertStringContainsString('Service queue item will not be processed because its initiator is the existing client', implode(' ', $this->logger->getInfoMessages()));
  }

}
