<?php

namespace FiloBlu\Esb\Model\Publisher\Db;

use DateTime;
use FiloBlu\Esb\Api\Data\MessageInterface;
use FiloBlu\Esb\Api\Data\PublisherInterface;
use FiloBlu\Esb\Api\Data\QueueItemInterface;
use FiloBlu\Esb\Api\Data\QueueItemInterfaceFactory;
use FiloBlu\Esb\Api\Data\QueueMetadataInterface;
use FiloBlu\Esb\Api\Data\StatusInterface;
use FiloBlu\Esb\Api\Data\StatusInterfaceFactory;
use FiloBlu\Esb\Api\QueueItemRepositoryInterface;

/**
 * Class MySql
 * @package FiloBlu\Esb\Model\Publisher\Db
 */
class MySql implements PublisherInterface
{
    /**
     * @var QueueItemRepositoryInterface
     */
    private $repository;
    /**
     * @var QueueItemInterfaceFactory
     */
    private $queueItemFactory;
    /**
     * @var StatusInterfaceFactory
     */
    private $statusFactory;

    /**
     * MySql constructor.
     * @param QueueItemInterfaceFactory $queueItemFactory
     * @param QueueItemRepositoryInterface $repository
     * @param StatusInterfaceFactory $statusFactory
     */
    public function __construct(
        QueueItemInterfaceFactory $queueItemFactory,
        QueueItemRepositoryInterface $repository,
        StatusInterfaceFactory $statusFactory
    ) {
        $this->repository = $repository;
        $this->queueItemFactory = $queueItemFactory;
        $this->statusFactory = $statusFactory;
    }

    /**
     * @inheritDoc
     */
    public function publish(MessageInterface $message, string $eventCode, QueueMetadataInterface $metadata): StatusInterface
    {
        /** @var QueueItemInterface $queueItem */
        $queueItem = $this->queueItemFactory->create();
        /** @var StatusInterface $status */
        $status = $this->statusFactory->create();
        $status->setCode(StatusInterface::PENDING);
        $queueItem
            ->setStatus($status)
            ->setEvent($eventCode)
            ->setMessage($message)
            ->setMessageHash(sha1($message->getPayload()->toJson()))
            ->setFrom($metadata->getFrom())
            ->setTo($metadata->getTo())
            ->setPublishedAt($metadata->getPublishedAt())
            ->setExecutableAfter($metadata->getExecutableAfter());
        $this->repository->save($queueItem);
        return $queueItem->getStatus();
    }
}
