<?php

namespace Drupal\languagewire_translation_provider\Test\Database;

use Drupal\languagewire_translation_provider\Adapter\Database\LanguageWireConfigurationItemRepositoryInterface;
use Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtTranslatorInterface;
use Drupal\languagewire_translation_provider\Client\WorkArea;
use Drupal\languagewire_translation_provider\Database\TypedWorkAreaRepository;
use PHPUnit\Framework\TestCase;
use stdClass;

/**
 * Typed Work Area Repository Test.
 */
class TypedWorkAreaRepositoryTest extends TestCase {
  use \Prophecy\PhpUnit\ProphecyTrait;

  /**
   * Config Item Repository .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy
   */
  private $configItemRepository;

  /**
   * Translator .
   *
   * @var \Prophecy\Prophecy\ObjectProphecy
   */
  private $translator;

  /**
   * Set Up .
   */
  protected function setUp(): void {
    $this->configItemRepository = $this->prophesize(LanguageWireConfigurationItemRepositoryInterface::class);
    $this->translator = $this->prophesize(TmgmtTranslatorInterface::class);
  }

  /**
   * Removes All Configuration Items Stored For Translator .
   *
   * @test
   */
  public function removesAllConfigurationItemsStoredForTranslator() {
    $translator = $this->translator->reveal();
    $repository = $this->repository();

    $repository->removeAll($translator);

    $this->configItemRepository->removeAll($translator, 'work_area')
      ->shouldHaveBeenCalled();
  }

  /**
   * Saves All Configuration Items For Translator .
   *
   * @test
   */
  public function savesAllConfigurationItemsForTranslator() {
    $translator = $this->translator->reveal();
    $items = [];
    $repository = $this->repository();

    $repository->saveAll($items, $translator);

    $this->configItemRepository->saveAll($items, $translator, 'work_area')
      ->shouldHaveBeenCalled();
  }

  /**
   * Fetches All Configuration Items For Translator .
   *
   * @test
   */
  public function fetchesAllConfigurationItemsForTranslator() {
    $translator = $this->translator->reveal();
    $databaseItem = $this->databaseItem();
    $this->configItemRepository->getAll($translator, 'work_area')
      ->willReturn([$databaseItem]);
    $repository = $this->repository();

    $result = $repository->getAll($translator);

    $this->assertCount(1, $result);
    $workArea = $result[0];
    $this->assertInstanceOf(WorkArea::class, $workArea);
    $this->assertSame($databaseItem->item_id, $workArea->id());
    $this->assertSame($databaseItem->name, $workArea->name());
  }

  /**
   * Fetches Work Area By Id .
   *
   * @test
   */
  public function fetchesWorkAreaById(): void {
    $workAreaId = 1;
    $translator = $this->translator->reveal();
    $databaseItem = $this->databaseItem();
    $this->configItemRepository->getByIdAndType($translator, $workAreaId, 'work_area')
      ->willReturn($databaseItem);
    $repository = $this->repository();

    $workArea = $repository->getById($workAreaId, $translator);

    $this->assertInstanceOf(WorkArea::class, $workArea);
    $this->assertSame($databaseItem->item_id, $workAreaId);
    $this->assertSame($databaseItem->name, $workArea->name());
  }

  /**
   * Repository .
   */
  private function repository(): TypedWorkAreaRepository {
    return new TypedWorkAreaRepository($this->configItemRepository->reveal());
  }

  /**
   * Database Item .
   */
  private function databaseItem(): stdClass {
    $item = new stdClass();
    $item->item_id = 1;
    $item->name = 'Foo';

    return $item;
  }

}
