<?php

namespace Drupal\Tests\acquia_contenthub\Unit\Client;

use Drupal\acquia_contenthub\AcquiaContentHubEvents;
use Drupal\acquia_contenthub\Client\ClientMetaDataBuilder;
use Drupal\acquia_contenthub\Event\ClientMetaDataEvent;
use Drupal\acquia_contenthub\EventSubscriber\CdfAttributes\AchVersionAttribute;
use Drupal\acquia_contenthub\EventSubscriber\CdfAttributes\ValidSslAttribute;
use Drupal\acquia_contenthub\PubSubModuleStatusChecker;
use Drupal\acquia_contenthub\Settings\ConnectionDetailsInterface;
use Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Tests client metadata builder.
 *
 * @coversDefaultClass \Drupal\acquia_contenthub\Client\ClientMetaDataBuilder
 *
 * @package acquia_contenthub
 */
class ClientMetaDataBuilderTest extends UnitTestCase {

  /**
   * Pub Sub module status checker.
   *
   * @var \Drupal\acquia_contenthub\PubSubModuleStatusChecker|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $moduleStatusChecker;

  /**
   * Ach Version Handler.
   *
   * @var \Drupal\acquia_contenthub\EventSubscriber\CdfAttributes\AchVersionAttribute|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $achVersionHandler;

  /**
   * Valid Ssl Handler.
   *
   * @var \Drupal\acquia_contenthub\EventSubscriber\CdfAttributes\ValidSslAttribute|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $validSslHandler;

  /**
   * Event dispatcher.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\Prophecy\Prophecy\ObjectProphecy
   */
  protected $dispatcher;

  /**
   * Content Hub connection details.
   *
   * @var \Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface
   */
  protected ContentHubConfigurationInterface $achConnectionDetails;

  /**
   * SUT.
   *
   * @var \Drupal\acquia_contenthub\Client\ClientMetaDataBuilder
   */
  protected ClientMetaDataBuilder $sut;

  /**
   * {@inheritDoc}
   */
  public function setUp(): void {
    parent::setUp();
    $this->moduleStatusChecker = $this->prophesize(PubSubModuleStatusChecker::class);
    $this->achVersionHandler = $this->prophesize(AchVersionAttribute::class);
    $this->validSslHandler = $this->prophesize(ValidSslAttribute::class);
    $this->dispatcher = $this->prophesize(EventDispatcherInterface::class);
  }

  /**
   * @covers ::buildClientMetadata
   *
   * @throws \Exception
   */
  public function testBuildClientMetaData(): void {
    $this->validSslHandler
      ->getValidStatusForSite()
      ->shouldBeCalled()
      ->willReturn(TRUE);
    $this->achVersionHandler
      ->getAchVersion()
      ->shouldBeCalled()
      ->willReturn('3.3.0');
    $this->moduleStatusChecker
      ->isPublisher()
      ->shouldBeCalled()
      ->willReturn(TRUE);
    $this->moduleStatusChecker
      ->isSubscriber()
      ->shouldBeCalled()
      ->willReturn(FALSE);
    // Add dynamic event subscriber to client metadata
    // event to add additional metadata.
    $this->dispatcher
      ->dispatch(Argument::type(ClientMetaDataEvent::class), AcquiaContentHubEvents::CLIENT_METADATA)
      ->shouldBeCalled()
      ->will(function ($args) {
        /** @var \Drupal\acquia_contenthub\Event\ClientMetaDataEvent $event */
        $event = $args[0];
        $event->setAdditionalConfig(['api_key' => 'some-api-key']);
        return $event;
      });
    $connection_details = $this->prophesize(ConnectionDetailsInterface::class);
    $connection_details->shouldUseSingleEntityPayload()->willReturn(TRUE);
    $connection_details->getSyndicationMode()->willReturn('push');
    $ch_configurations = $this->prophesize(ContentHubConfigurationInterface::class);
    $ch_configurations
      ->getConnectionDetails()
      ->willReturn($connection_details->reveal());
    $this->sut = new ClientMetaDataBuilder(
      $this->achVersionHandler->reveal(),
      $this->validSslHandler->reveal(),
      $this->moduleStatusChecker->reveal(),
      $this->dispatcher->reveal(),
      $ch_configurations->reveal()
    );
    $client_metadata = $this->sut->buildClientMetadata()->toArray();
    $this->assertEquals($this->sut::CLIENT_TYPE, $client_metadata['client_type']);
    $this->assertEquals(TRUE, $client_metadata['is_publisher']);
    $this->assertEquals(FALSE, $client_metadata['is_subscriber']);
    $this->assertEquals('3.3.0', $client_metadata['config']['ch_version']);
    $this->assertEquals(\Drupal::VERSION, $client_metadata['config']['drupal_version']);
    $this->assertEquals(TRUE, $client_metadata['config']['valid_ssl']);
    $this->assertEquals('some-api-key', $client_metadata['config']['api_key']);
    $this->assertEquals('push', $client_metadata['syndication_strategy']);
  }

}
