<?php

namespace Drupal\Tests\acquiadam_asset_import\Kernel\Drush\Commands;

use Drupal\acquiadam_asset_import\Drush\Commands\AssetImportDrushCommands;
use Drupal\Tests\acquia_dam\Kernel\AcquiaDamKernelTestBase;

/**
 * Tests the Drush command for importing Acquia DAM assets.
 *
 * @coversDefaultClass \Drupal\acquiadam_asset_import\Drush\Commands\AssetImportDrushCommands
 *
 * @group acquiadam_asset_import
 */
class AssetImportDrushCommandTest extends AcquiaDamKernelTestBase {

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

  /**
  * The QueueFactory.
  *
  * @var \Drupal\Core\Queue\QueueFactory
  */
  protected $queueFactory;

  /**
  * The command under test.
  *
  * @var \Drupal\acquiadam_asset_import\Drush\Commands\AssetImportDrushCommands
  */
  protected $command;

  /**
   * The encoded category name.
   *
   * @var string
   */
  protected $encodedCategoryName;

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

    $this->installConfig(['acquiadam_asset_import']);
    $this->installEntitySchema('media_type');
    $this->installEntitySchema('media');
    $this->installEntitySchema('file');

    // Create a media type for testing.
    $media_type_storage = $this->container->get('entity_type.manager')->getStorage('media_type');
    $media_type = $media_type_storage->create([
      'id' => 'acquia_dam_video_asset',
      'label' => 'Acquia DAM: Video',
      'source' => 'acquia_dam_asset:video',
      'source_configuration' => [
        'source_field' => 'acquia_dam_asset_id',
        'download_assets' => false,
      ],
    ]);
    $media_type->save();

    // Initialize services.
    $this->queueFactory = $this->container->get('queue');

    // Initialize the command under test.
    $this->command = new AssetImportDrushCommands(
      $this->container->get('acquiadam_asset_import.asset_queue'),
      $this->queueFactory,
      $this->container->get('plugin.manager.queue_worker'),
    );
    $this->encodedCategoryName = base64_encode('Testing');
  }

  /**
  * Tests the queueAssets method when categories are configured.
  *
  * @covers ::queueAssets
  */
  public function testQueueAssetsSuccess(): void {
    $this->config('acquiadam_asset_import.settings')
      ->set('categories', [$this->encodedCategoryName => []])
      ->save();

    $this->command->queueAssets();
    $this->assertSame(1, $this->queueFactory->get('acquia_dam_asset_import')->numberOfItems());
  }

  /**
  * Tests the queueAssets method when no categories are configured.
  *
  * @covers ::queueAssets
  */
  public function testQueueAssetsNoAssets(): void {
    $this->config('acquiadam_asset_import.settings')
      ->set('categories', [])
      ->save();

    $this->command->queueAssets();
    $this->assertSame(0, $this->queueFactory->get('acquia_dam_asset_import')->numberOfItems());
  }

  /**
  * Tests the importAssets and processQueue method.
  *
  * @covers ::processQueue
  * @covers ::importAssets
  */
  public function testImportAssets(): void {
    $this->config('acquiadam_asset_import.settings')
      ->set('categories', [$this->encodedCategoryName => []])
      ->save();

    // Queue assets for import.
    $this->assertSame(0, $this->queueFactory->get('acquia_dam_asset_import')->numberOfItems());
    // Queue assets based on the configured categories.
    $this->command->queueAssets();
    // Assert that one asset is queued.
    $this->assertSame(1, $this->queueFactory->get('acquia_dam_asset_import')->numberOfItems());

    // Process the queue.
    $this->command->processQueue();
    // Assert that the queue is empty after processing.
    $this->assertSame(0, $this->queueFactory->get('acquia_dam_asset_import')->numberOfItems());

    // Assert that the media item was created.
    $media_storage = $this->container->get('entity_type.manager')->getStorage('media');
    $media_items = $media_storage->loadByProperties(['bundle' => 'acquia_dam_video_asset']);
    $this->assertCount(1, $media_items, 'One media item was created from the queued asset.');

    // Asset that existing assets are not duplicated in queue.
    $this->command->queueAssets();
    // Assert that one asset is queued.
    $this->assertSame(0, $this->queueFactory->get('acquia_dam_asset_import')->numberOfItems());
  }
}
