<?php

namespace Drupal\languagewire_translation_provider\Test\Client;

use Drupal\languagewire_translation_provider\Adapter\TMGMT\LanguageMapping;
use Drupal\languagewire_translation_provider\api\Libraries\Project\ProjectSpecification;
use Drupal\languagewire_translation_provider\api\Libraries\Project\ProjectSpecificationBaseInterface;
use Drupal\languagewire_translation_provider\api\Models\ConfigurationModel;
use Drupal\languagewire_translation_provider\Client\ClientInterface;
use Drupal\languagewire_translation_provider\Client\Product;
use Drupal\languagewire_translation_provider\Platform\Document\ValidDocument;
use Drupal\languagewire_translation_provider\Platform\Services\ServiceInterface;
use Drupal\languagewire_translation_provider\Test\Builder\LanguageMappingBuilder;
use Drupal\languagewire_translation_provider\Test\Builder\ServiceBuilder;
use Drupal\languagewire_translation_provider\Test\Builder\ValidDocumentBuilder;
use PHPUnit\Framework\TestCase;

/**
 * LanguageWire Project Specification Test .
 */
class LanguageWireProjectSpecificationTest extends TestCase {
  use \Prophecy\PhpUnit\ProphecyTrait;

  /**
   * Client .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy
   */
  protected $client;

  /**
   * Set Up .
   */
  protected function setUp(): void {
    $this->client = $this->prophesize(ClientInterface::class);
  }

  /**
   * It Creates Project Specification .
   *
   * @test
   */
  public function itCreatesProjectSpecification(): void {
    $service = (new ServiceBuilder())->build();
    $validDocument = (new ValidDocumentBuilder())->build();
    $language = (new LanguageMappingBuilder())->build();
    $projectUuid = 'uuid';
    $title = 'Foo';
    $briefing = 'Briefing';

    $configurationModel = new ConfigurationModel();
    $configurationModel->setFields([
      'productID' => $service->id(),
      'workAreaID' => $service->workAreaId(),
      'translationMemoryID' => $service->translationMemoryId(),
      'termBaseID' => $service->termBaseId(),
      'invoicingAccountID' => $service->invoicingAccountId(),
      'userID' => $service->userId(),
    ]);

    $platformProjectSpecs = new ProjectSpecification(
      [$validDocument->platformId()],
      [$language->remoteLanguage()],
      $projectUuid,
      $title,
      $configurationModel,
      new \DateTime('+1 day', new \DateTimeZone('UTC')),
      $briefing
    );

    $this->assertProjectSpecification($title, $platformProjectSpecs, $briefing, $validDocument, $language, $service);
    $this->assertSame($service->id(), $platformProjectSpecs->getConfiguration()->getProductId());
    $this->assertEquals($service->deadline()->toUtc()->format(ProjectSpecificationBaseInterface::DEADLINE_FORMAT), $platformProjectSpecs->getDeadline());
  }

  /**
   * It Tests Project Specification .
   */
  private function assertProjectSpecification(string $title, ProjectSpecification $platformProjectSpecs, string $briefing, ValidDocument $validDocument, LanguageMapping $language, ServiceInterface $service): void {
    $this->assertSame($title, $platformProjectSpecs->getTitle());
    $this->assertNotNull($platformProjectSpecs->getCorrelationId());
    $this->assertSame($briefing, $platformProjectSpecs->getBriefing());

    $this->assertEquals([$validDocument->platformId()], $platformProjectSpecs->getSourceDocuments());
    $this->assertEquals([$language->remoteLanguage()], $platformProjectSpecs->getTargetLanguages());

    $configurations = $platformProjectSpecs->getConfiguration();

    $this->assertSame($service->workAreaId(), $configurations->getWorkAreaId());
    $this->assertSame($service->translationMemoryId(), $configurations->getTranslationMemoryId());
    $this->assertSame($service->termBaseId(), $configurations->getTermBaseId());
    $this->assertSame($service->invoicingAccountId(), $configurations->getInvoicingAccountId());
    $this->assertSame($service->userId(), $configurations->getUserId());
  }
}
