<?php

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

use Acquia\ContentHubClient\CDF\CDFObject;
use Acquia\ContentHubClient\CDFAttribute;
use Drupal\acquia_contenthub\Event\LoadLocalEntityEvent;
use Drupal\acquia_contenthub\EventSubscriber\LoadLocalEntity\LoadUserByNameOrMail;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\depcalc\DependencyStack;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\Tests\acquia_contenthub\Unit\Helpers\LoggerMock;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
use Psr\Log\LoggerInterface;

/**
 * Tests loading of local user.
 *
 * @coversDefaultClass \Drupal\acquia_contenthub\EventSubscriber\LoadLocalEntity\LoadUserByNameOrMail
 *
 * @group acquia_contenthub
 *
 * @requires module depcalc
 */
class LoadLocalMatchingUserTest extends EntityKernelTestBase {

  /**
   * The CDF object.
   *
   * @var \Acquia\ContentHubClient\CDF\CDFObjectInterface|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $cdfObject;

  /**
   * User entity.
   *
   * @var \Drupal\user\UserInterface
   */
  protected UserInterface $user;

  /**
   * Logger mock.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected LoggerInterface $logger;

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

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

    $this->installEntitySchema('user');
    $this->user = User::create([
      'name' => 'test_user',
    ]);
    $this->user->save();
    $this->logger = new LoggerMock();
    $this->initialiseCdfObject();
  }

  /**
   * Testing loading of user by name.
   *
   * @throws \Exception
   */
  public function testUserLoadByName(): void {
    $local_entity_event = new LoadLocalEntityEvent($this->cdfObject->reveal(), new DependencyStack());
    $sut = new LoadUserByNameOrMail($this->logger);
    $sut->onLoadLocalEntity($local_entity_event);
    /** @var \Drupal\user\UserInterface $entity */
    $entity = $local_entity_event->getEntity();

    $this->assertSame($this->user->uuid(), $entity->uuid());
    $this->assertSame($this->user->getAccountName(), $entity->getAccountName());
    $log_messages = $this->logger->getLogMessages();
    $this->assertEquals(
      "Could not load user with mail, hence loaded by name. Having uuid: {$this->user->uuid()}",
      $log_messages[RfcLogLevel::INFO][0]
    );
  }

  /**
   * Initialises Cdf object for user.
   */
  protected function initialiseCdfObject(): void {
    $type_cdf_attribute = $this->prophesize(CDFAttribute::class);
    $type_cdf_attribute->getValue()->willReturn([
      CDFObject::LANGUAGE_UNDETERMINED => 'user',
    ]);
    $this->cdfObject = $this->prophesize(CDFObject::class);
    $this->cdfObject->getType()->willReturn('drupal8_content_entity');
    $this->cdfObject->getAttribute('entity_type')->willReturn($type_cdf_attribute->reveal());
    $this->cdfObject->getAttribute('is_anonymous')->willReturn(NULL);
    $this->cdfObject->getAttribute('mail')->willReturn(NULL);
    $name_cdf_attribute = $this->prophesize(CDFAttribute::class);
    $name_cdf_attribute->getValue()->willReturn([
      CDFObject::LANGUAGE_UNDETERMINED => $this->user->getAccountName(),
    ]);
    $this->cdfObject->getAttribute('username')->willReturn($name_cdf_attribute->reveal());
    $this->cdfObject->getUuid()->willReturn($this->user->uuid());
  }

}
