<?php

namespace Drupal\Tests\acquia_contenthub_publisher\Kernel;

use Drupal\acquia_contenthub\ContentHubCommonActions;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\Tests\acquia_contenthub\Kernel\Traits\FieldTrait;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;

/**
 * Tests dependency field exclusion.
 *
 * @group acquia_contenthub_publisher
 *
 * @requires module depcalc
 */
class DependencyFieldExclusionTest extends EntityKernelTestBase {

  use ContentTypeCreationTrait;
  use NodeCreationTrait;
  use FieldTrait;

  /**
   * {@inheritDoc}
   */
  protected static $modules = [
    'acquia_contenthub',
    'acquia_contenthub_publisher',
    'depcalc',
    'field',
    'filter',
    'node',
    'text',
    'user',
    'system',
  ];

  /**
   * Content Hub Common Actions Service.
   *
   * @var \Drupal\acquia_contenthub\ContentHubCommonActions
   */
  protected ContentHubCommonActions $commonAction;

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

    $this->installConfig('node');
    $this->installConfig('filter');

    $this->installEntitySchema('node');
    $this->installEntitySchema('user');
    $this->installSchema('user', ['users_data']);
    $this->installSchema('acquia_contenthub_publisher', ['acquia_contenthub_publisher_export_tracking']);

    $this->createContentType([
      'type' => 'article',
      'name' => 'Article',
    ]);
    $this->commonAction = $this->container->get('acquia_contenthub_common_actions');
  }

  /**
   * Tests CDF after field exclusion.
   */
  public function testCdfAfterExcludingFields(): void {
    $node = $this->createNode([
      'type' => 'article',
      'title' => 'Test Article',
      'body' => [
        'value' => 'Test Body',
        'format' => 'plain_text',
      ],
    ]);

    $cdf_objects = $this->commonAction->getEntityCdf($node);
    /** @var \Acquia\ContentHubClient\CDF\CDFObject $cdf */
    $cdf = reset($cdf_objects);
    $metadata = $cdf->getMetadata();
    $this->assertArrayHasKey('title', $metadata['field'], 'Title field is present.');
    $this->assertArrayHasKey('body', $metadata['field'], 'Body field is present.');

    $excluded_fields = [
      'title',
      'body',
    ];
    /** @var \Drupal\acquia_contenthub_publisher\Libs\ExcludeSettingsInterface $exclude_settings */
    $exclude_settings = $this->container->get('acquia_contenthub_publisher.exclude.settings');
    $exclude_settings->excludeFields('node', 'article', $excluded_fields);
    $exclude_settings->save();

    $cdf_objects = $this->commonAction->getEntityCdf($node);
    /** @var \Acquia\ContentHubClient\CDF\CDFObject $cdf */
    $cdf = reset($cdf_objects);
    $metadata = $cdf->getMetadata();
    $this->assertArrayNotHasKey('title', $metadata['field'], 'Title field is excluded.');
    $this->assertArrayNotHasKey('body', $metadata['field'], 'Body field is excluded.');
  }

  /**
   * Tests dependencies after entity reference field exclusion.
   */
  public function testReferenceFieldExclusion(): void {
    // Create field field_reference_node of entity_reference type.
    $this->createEntityReferenceField('node', 'article', 'field_reference_node', 'Child Node', 'node');

    $child_node = $this->createNode([
      'type' => 'article',
    ]);
    $parent_node = $this->createNode([
      'type' => 'article',
      'field_reference_node' => $child_node,
    ]);

    $cdf_objects = $this->commonAction->getEntityCdf($parent_node);
    /** @var \Acquia\ContentHubClient\CDF\CDFObject $cdf */
    $cdf = reset($cdf_objects);
    $dependencies = $cdf->getDependencies();
    $this->assertArrayHasKey($child_node->uuid(), $dependencies, 'Child node is a dependency of parent node.');
    $metadata = $cdf->getMetadata();
    $this->assertArrayHasKey('field_reference_node', $metadata['field'], 'field_reference_node is present in metadata.');

    $excluded_fields = [
      'field_reference_node',
    ];
    /** @var \Drupal\acquia_contenthub_publisher\Libs\ExcludeSettingsInterface $exclude_settings */
    $exclude_settings = $this->container->get('acquia_contenthub_publisher.exclude.settings');
    $exclude_settings->excludeFields('node', 'article', $excluded_fields);
    $exclude_settings->save();

    $cdf_objects = $this->commonAction->getEntityCdf($parent_node);
    /** @var \Acquia\ContentHubClient\CDF\CDFObject $cdf */
    $cdf = reset($cdf_objects);
    $dependencies = $cdf->getDependencies();
    $this->assertArrayNotHasKey($child_node->uuid(), $dependencies, 'Child node is not a dependency of parent node.');
    $metadata = $cdf->getMetadata();
    $this->assertArrayNotHasKey('field_reference_node', $metadata['field'], 'field_reference_node is not present in metadata.');
  }

}
