<?php
declare(strict_types=1);
namespace App\Domains\Word\Application\UseCase;
use App\Domains\User\Domain\Entity\User;
use App\Domains\Word\Domain\Entity\Word;
use App\Domains\Word\Domain\Enum\Language;
use App\Domains\Word\Domain\Mapper\WordMapper;
use App\Domains\Word\Domain\Service\ImageGenerationService;
use App\Domains\Word\Domain\Service\TranslateService;
use App\Domains\Word\Domain\Service\WordCacheService;
use App\Domains\Word\Domain\Service\WordService;
use App\Domains\Word\Infrastructure\Adapter\UserAdapter;
use App\Domains\Word\Infrastructure\Adapter\UserWordAdapter;
final class TranslateUseCase
{
public function __construct(
private readonly TranslateService $translateService,
private readonly WordService $wordService,
private readonly WordCacheService $wordCacheService,
private readonly WordMapper $wordMapper,
private readonly UserWordAdapter $userWordAdapter,
private readonly UserAdapter $userAdapter,
private readonly ImageGenerationService $imageGenerationService,
) {
}
public function execute(
string $wordToTranslate,
Language $languageFrom,
Language $languageTo,
User $user,
): Word {
$cached = $this->wordCacheService->getWord(
$wordToTranslate,
$languageFrom->value,
$languageTo->value,
$user->getId(),
);
// if ($cached !== null) {
// return $this->translationResponseMapper->fromWordObject(
// $this->wordMapper->fromArray($cached)
// );
// }
$word = $this->wordService->isWordExist(
word: $wordToTranslate,
languageFrom: $languageFrom,
languageTo: $languageTo,
);
if ($word) {
$isWordAssignedToUser = $this->userWordAdapter->isWordAssignedToUser(
$word,
$user,
);
if (!$isWordAssignedToUser) {
$this->userWordAdapter->addWordToUser(
$word,
$user,
);
}
} else {
$word = $this->translateService->translate(
$wordToTranslate,
$languageFrom,
$languageTo,
$user,
);
$this->userWordAdapter->addWordToUser(
$word,
$user,
);
// Generate image for new words only
$imageFilename = $this->imageGenerationService->generateWordImage($word);
if ($imageFilename) {
$word->setImageFilename($imageFilename);
}
}
// cash the result into the redis
$this->wordCacheService->cacheWord(
$this->wordMapper->toArray($word),
$user->getId()
);
// Record user usage
$this->userAdapter->recordUserUsage($user);
// TODO: metrics, how long does it take, how many requests
return $word;
}
}