<?php

declare(strict_types=1);

namespace Drupal\Tests\acquia_dam\Kernel;

use Drupal\acquia_dam\Client\AcquiaDamClient;
use Drupal\acquia_dam\Exception\DamClientException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;

/**
 * Kernel tests for AcquiaDamClient search with released and include_deleted.
 *
 * Exercises the full search flow through the mocked HTTP middleware. The
 * middleware does not interpret the query itself — it returns fixture files
 * based on pattern matching — so these tests verify that the flags are
 * accepted and forwarded without error, not that the API applies the filter
 * server-side.
 *
 * @coversDefaultClass \Drupal\acquia_dam\Client\AcquiaDamClient
 * @group acquia_dam_kernel
 */
#[CoversClass(AcquiaDamClient::class)]
#[Group('acquia_dam_kernel')]
final class AcquiaDamSearchTest extends AcquiaDamKernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->drupalSetUpCurrentUser();
  }

  /**
   * Returns the site-level DAM client from the factory.
   *
   * @return \Drupal\acquia_dam\Client\AcquiaDamClient
   *   The client instance.
   */
  private function getClient(): AcquiaDamClient {
    return $this->container->get('acquia_dam.client.factory')->getSiteClient();
  }

  /**
   * Tests search with released and include_deleted flag combinations.
   *
   * @param string $query
   *   The search query.
   * @param bool $include_deleted
   *   Whether to include deleted assets.
   * @param bool $released
   *   Whether to filter by active release/expiration status.
   * @param int|null $expected_count
   *   Expected number of result items, or NULL if an exception is expected.
   */
  #[DataProvider('providerSearchScenarios')]
  public function testSearch(string $query, bool $include_deleted, bool $released, ?int $expected_count): void {
    $client = $this->getClient();

    if ($expected_count === NULL) {
      $this->expectException(DamClientException::class);
    }

    $result = $client->search(
      $query,
      '-created_date',
      10,
      0,
      ['file_properties'],
      $include_deleted,
      FALSE,
      $released,
    );

    if ($expected_count !== NULL) {
      self::assertArrayHasKey('items', $result);
      self::assertArrayHasKey('total_count', $result);
      self::assertCount($expected_count, $result['items']);
    }
  }

  /**
   * Data provider for testSearch().
   *
   * getSearch.json has 2 items (all active).
   * getSearchIncludeDeleted.json has 3 items (2 active + 1 deleted).
   *
   * @return array<string, array{mixed}>
   */
  public static function providerSearchScenarios(): array {
    return [
      'basic search' => ['ft:(image)', FALSE, FALSE, 2],
      'released only' => ['ft:(image)', FALSE, TRUE, 2],
      'include deleted only' => ['ft:(image)', TRUE, FALSE, 3],
      'released + include deleted' => ['ft:(image)', TRUE, TRUE, 3],
    ];
  }

}
