<?php
namespace App\Entity\Profile;
use App\Entity\ContainsDomainEvents;
use App\Entity\DomainEventsRecorderTrait;
use App\Event\Profile\FileProcessingTaskWasCompleted;
use App\Message\ProcessUploadedVideoMessage;
use DateTimeImmutable;
use DateTimeZone;
use Doctrine\ORM\Mapping AS ORM;
#[ORM\Entity]
#[ORM\Table(name: 'file_processing_tasks')]
class FileProcessingTask implements ContainsDomainEvents
{
use DomainEventsRecorderTrait;
public const STATE_PENDING = 'pending';
public const STATE_PROCESSING = 'processing';
public const STATE_COMPLETED = 'completed';
public const STATE_FAILED = 'failed';
#[ORM\Id, ORM\GeneratedValue(strategy: 'AUTO'), ORM\Column(name: 'id', type: 'integer')]
private int $id;
#[ORM\JoinColumn(name: 'profile_id', referencedColumnName: 'id')]
#[ORM\ManyToOne(targetEntity: Profile::class, inversedBy: 'processingFiles')]
protected Profile $profile;
#[ORM\Column(name: 'path', type: 'string', length: 128)]
protected string $path;
#[ORM\Column(name: 'state', type: 'string', length: 32)]
protected string $state;
#[ORM\Column(name: 'added_at', type: 'datetimetz_immutable')]
protected DateTimeImmutable $addedAt;
#[ORM\Column(name: 'started_at', type: 'datetimetz_immutable', nullable: true)]
protected ?DateTimeImmutable $startedAt = null;
#[ORM\Column(name: 'last_error', type: 'text', nullable: true)]
protected ?string $lastError = null;
public function __construct(Profile $profile, string $path)
{
$this->profile = $profile;
$this->path = $path;
$this->state = self::STATE_PENDING;
$this->addedAt = new DateTimeImmutable('now', new DateTimeZone('UTC'));
}
public function start(): void
{
$this->state = self::STATE_PROCESSING;
$this->startedAt = new DateTimeImmutable('now', new DateTimeZone('UTC'));
}
public function isStarted(): bool
{
return $this->state === self::STATE_PROCESSING;
}
public function completeVideoTranscoding(string $videoPath, string $posterPath): void
{
$this->state = self::STATE_COMPLETED;
$this->profile->addVideo($videoPath, $posterPath);
$this->recordEvent(new FileProcessingTaskWasCompleted($this->profile, $this));
}
public function isCompleted(): bool
{
return $this->state === self::STATE_COMPLETED;
}
public function fail(string $errorMessage): void
{
$this->state = self::STATE_FAILED;
$this->lastError = $errorMessage;
}
public function createCommandToProcessUploadedVideo(): ProcessUploadedVideoMessage
{
return new ProcessUploadedVideoMessage(
$this->id,
$this->profile->getId(),
$this->path,
);
}
}