<?php

namespace Drupal\languagewire_translation_provider\Test\Adapter\PreviewSite;

use Drupal\languagewire_translation_provider\Adapter\Entity\EntityInterface;
use Drupal\languagewire_translation_provider\Adapter\PreviewSite\CleanupAction\PreviewSiteCompositeCleanupAction;
use Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewSiteBuilder;
use Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewSiteBuildFactory;
use Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewSiteBuildRepositoryInterface;
use Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewSiteHtmlPreviewGenerator;
use Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewStrategyRepositoryInterface;
use Drupal\languagewire_translation_provider\Adapter\SystemInterface;
use Drupal\languagewire_translation_provider\Content\HtmlPreview\Result\HtmlPreviewResult;
use Drupal\languagewire_translation_provider\Domain\Document;
use Drupal\languagewire_translation_provider\Test\Builder\Adapter\PreviewSite\PreviewSiteBuildBuilder;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Psr\Log\LoggerInterface;

/**
 * Preview Site Html Preview Generator Test .
 */
class PreviewSiteHtmlPreviewGeneratorTest extends TestCase {
  use \Prophecy\PhpUnit\ProphecyTrait;

  /**
   * Preview Site Build Factory .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy|\Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewSiteBuildFactory
   */
  protected ObjectProphecy $previewSiteBuildFactory;

  /**
   * Preview Site Builder .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy|\Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewSiteBuilder
   */
  protected ObjectProphecy $previewSiteBuilder;

  /**
   * Build Repository .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy|\Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewSiteBuildRepositoryInterface
   */
  protected ObjectProphecy $buildRepository;

  /**
   * Strategy Repository .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy|\Drupal\languagewire_translation_provider\Adapter\PreviewSite\PreviewStrategyRepositoryInterface
   */
  protected ObjectProphecy $strategyRepository;

  /**
   * Preview Site Cleanup Action .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy|\Drupal\languagewire_translation_provider\Adapter\PreviewSite\CleanupAction\PreviewSiteCompositeCleanupAction
   */
  protected ObjectProphecy $previewSiteCleanupAction;

  /**
   * System .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy|\Drupal\languagewire_translation_provider\Adapter\SystemInterface
   */
  protected ObjectProphecy $system;

  /**
   * Set Up .
   */
  protected function setUp(): void {
    $this->previewSiteBuildFactory = $this->prophesize(PreviewSiteBuildFactory::class);
    $this->previewSiteBuilder = $this->prophesize(PreviewSiteBuilder::class);
    $this->buildRepository = $this->prophesize(PreviewSiteBuildRepositoryInterface::class);
    $this->strategyRepository = $this->prophesize(PreviewStrategyRepositoryInterface::class);
    $this->previewSiteCleanupAction = $this->prophesize(PreviewSiteCompositeCleanupAction::class);
    $this->system = $this->prophesize(SystemInterface::class);
    $logger = $this->prophesize(LoggerInterface::class);

    $this->previewSiteCleanupAction
      ->cleanUpResult(Argument::type(HtmlPreviewResult::class))
      ->willReturnArgument(0);
    $this->system->logger()->willReturn($logger->reveal());
    $this->system->realPath(Argument::type('string'))->willReturnArgument(0);
  }

  /**
   * When Content Is Provided Then Preview Is Generated .
   *
   * @test
   */
  public function whenContentIsProvidedThenPreviewIsGenerated(): void {
    $entity = $this->createEntity();
    $finalPreviewFolderPath = '/tmp/build_1';
    $strategyId = 'strategy_id';
    $temporaryArtifactsFolder = '/private/build_1';
    $build = (new PreviewSiteBuildBuilder())
      ->withId(1)
      ->withFolderPath($finalPreviewFolderPath)
      ->withStrategyId($strategyId)
      ->withTemporaryArtifactsBasePath($temporaryArtifactsFolder)
      ->build();

    $document = $this->prophesize(Document::class);
    $document->getTitle()->willReturn('Document Title');
    $documentObject = $document->reveal();
    $jobID = 1;

    $this->buildRepository->getById(1)->willReturn($build);
    $this->previewSiteBuildFactory->createSiteBuild($entity, $documentObject, $jobID)->willReturn($build);

    $this->buildRepository->deleteById(1)->shouldBeCalled();
    $this->strategyRepository->deleteById($strategyId)->shouldBeCalled();

    $generator = $this->createGenerator();
    $preview = $generator->generatePreviewForEntity($entity, $documentObject, $jobID);

    $this->assertSame($finalPreviewFolderPath, $preview->getHtmlPreviewFolderPath());
    $this->assertSame('build_1', $preview->getHtmlPreviewFolderName());
    $this->assertSame($temporaryArtifactsFolder, $preview->getTemporaryPreviewFolderPath());
  }

  /**
   * Create Entity .
   */
  private function createEntity() {
    $content = $this->prophesize(EntityInterface::class);
    return $content->reveal();
  }

  /**
   * Create Generator .
   */
  private function createGenerator(): PreviewSiteHtmlPreviewGenerator {
    return new PreviewSiteHtmlPreviewGenerator(
          $this->previewSiteBuildFactory->reveal(),
          $this->previewSiteBuilder->reveal(),
          $this->buildRepository->reveal(),
          $this->strategyRepository->reveal(),
          $this->previewSiteCleanupAction->reveal(),
          $this->system->reveal()
      );
  }

}
