<?php

namespace FiloBlu\Esb\Model;

use FiloBlu\Esb\Api\Data\ConsumerConfigurationInterface;
use FiloBlu\Esb\Api\Data\ConsumerInterface;
use FiloBlu\Esb\Api\Data\IdentifiableInterface;
use FiloBlu\Esb\Api\ObjectTypeLoaderInterface;
use FiloBlu\Esb\Api\ObjectTypeSaverInterface;
use FiloBlu\Esb\Api\RetryStrategyInterface;
use FiloBlu\Esb\Core\Id\UUID4GeneratorInterface;
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;

/**
 * Class ConsumerConfiguration
 * @package FiloBlu\Esb\Model
 */
class ConsumerConfiguration implements ConsumerConfigurationInterface
{
    /**
     * @var string
     */
    protected $bindingEvent;
    /**
     * @var string
     */
    protected $outputEvent;
    /**
     * @var DataObject
     */
    protected $parameters;
    /**
     * @var string
     */
    protected $id;
    /**
     * @var ConsumerInterface
     */
    protected $consumer;
    /**
     * @var RetryStrategyInterface
     */
    protected $retryStrategy;
    /**
     * @var int
     */
    protected $enable;
    /**
     * @var string
     */
    protected $label;
    /**
     * @var string
     */
    protected $uuid;
    /**
     * @var DataObjectFactory
     */
    protected $dataObjectFactory;

    /**
     * @var mixed
     */
    protected $retryStrategyConfiguration;
    /**
     * @var bool
     */
    protected $saveRequest;
    /**
     * @var bool
     */
    protected $setSaveResponse;
    /**
     * @var int
     */
    protected $priority = 1;
    /**
     * @var ObjectTypeLoaderInterface
     */
    protected $objectTypeLoader;
    /**
     * @var ObjectTypeSaverInterface
     */
    protected $objectTypeSaver;
    /**
     * @var UUID4GeneratorInterface
     */
    private $UUID4Generator;

    /**
     * @var int
     */
    private $triggerDelay = 0;

    /**
     * ConsumerConfiguration constructor.
     * @param RetryStrategyInterface $defaultRetryStrategy
     * @param UUID4GeneratorInterface $UUID4Generator
     * @param DataObjectFactory $dataObjectFactory
     */
    public function __construct(
        RetryStrategyInterface $defaultRetryStrategy,
        UUID4GeneratorInterface $UUID4Generator,
        DataObjectFactory $dataObjectFactory
    ) {
        $this->dataObjectFactory = $dataObjectFactory;
        $this->retryStrategy = $defaultRetryStrategy;
        $this->UUID4Generator = $UUID4Generator;
    }

    /**
     * @inheritDoc
     */
    public function getOutputEvent(): string
    {
        return $this->outputEvent;
    }

    /**
     * @inheritDoc
     */
    public function setOutputEvent($event): ConsumerConfigurationInterface
    {
        $this->outputEvent = $event;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getBindingEvent(): string
    {
        return $this->bindingEvent;
    }

    /**
     * @inheritDoc
     */
    public function setBindingEvent($event): ConsumerConfigurationInterface
    {
        $this->bindingEvent = $event;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getParameters(): DataObject
    {
        if (!$this->parameters) {
            $this->parameters = $this->dataObjectFactory->create();
        }
        return $this->parameters;
    }

    /**
     * @inheritDoc
     */
    public function setParameters(DataObject $parameters): ConsumerConfigurationInterface
    {
        $this->parameters = $parameters;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @inheritDoc
     */
    public function setId($id): IdentifiableInterface
    {
        $this->id = $id;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getConsumer(): ConsumerInterface
    {
        return $this->consumer->configure($this);
    }

    /**
     * @inheritDoc
     */
    public function setConsumer(ConsumerInterface $consumer): ConsumerConfigurationInterface
    {
        $this->consumer = $consumer;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getLabel(): string
    {
        return $this->label ?: '';
    }

    /**
     * @inheritDoc
     */
    public function setLabel(string $label): ConsumerConfigurationInterface
    {
        $this->label = $label;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function isEnabled(): bool
    {
        return $this->enable === self::STATUS_ENABLED;
    }

    /**
     * @inheritDoc
     */
    public function enable()
    {
        $this->enable = self::STATUS_ENABLED;
    }

    /**
     * @inheritDoc
     */
    public function disable()
    {
        $this->enable = self::STATUS_DISABLED;
    }

    /**
     * @inheritDoc
     */
    public function getRetryStrategy(): RetryStrategyInterface
    {
        return $this->retryStrategy;
    }

    /**
     * @inheritDoc
     */
    public function setRetryStrategy(RetryStrategyInterface $retryStrategy): ConsumerConfigurationInterface
    {
        $this->retryStrategy = $retryStrategy;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getUuid(): string
    {
        return $this->uuid ?: $this->UUID4Generator->generate();
    }

    /**
     * @inheritDoc
     */
    public function setUuid($uuid): IdentifiableInterface
    {
        $this->uuid = $uuid;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getRetryStrategyConfiguration()
    {
        return $this->retryStrategyConfiguration;
    }

    /**
     * @inheritDoc
     */
    public function setRetryStrategyConfiguration($configuration): ConsumerConfigurationInterface
    {
        $this->retryStrategyConfiguration = $configuration;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getSaveRequest(): bool
    {
        return $this->saveRequest;
    }

    /**
     * @inheritDoc
     */
    public function setSaveRequest(bool $save): ConsumerConfigurationInterface
    {
        $this->saveRequest = $save;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function setSaveResponse(bool $save): ConsumerConfigurationInterface
    {
        $this->setSaveResponse = $save;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getSaveResponse(): bool
    {
        return $this->saveRequest;
    }

    /**
     * @inheritDoc
     */
    public function getPriority(): int
    {
        return $this->priority;
    }

    /**
     * @inheritDoc
     */
    public function setPriority($priority): ConsumerConfigurationInterface
    {
        $this->priority = $priority;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function setObjectLoader(ObjectTypeLoaderInterface $objectTypeLoader): ConsumerConfigurationInterface
    {
        $this->objectTypeLoader = $objectTypeLoader;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getObjectLoader(): ObjectTypeLoaderInterface
    {
        return $this->objectTypeLoader;
    }

    /**
     * @inheritDoc
     */
    public function setObjectSaver(ObjectTypeSaverInterface $objectTypeSaver): ConsumerConfigurationInterface
    {
        $this->objectTypeSaver = $objectTypeSaver;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getObjectSaver(): ObjectTypeSaverInterface
    {
        return $this->objectTypeSaver;
    }

    /**
     * @return int
     */
    public function getTriggerDelay()
    {
        return (int)($this->triggerDelay ?? 0);
    }

    /**
     * @param $triggerDelay
     * @return \FiloBlu\Esb\Api\Data\ConsumerConfigurationInterface
     */
    public function setTriggerDelay($triggerDelay): ConsumerConfigurationInterface
    {
        $this->triggerDelay = (int)$triggerDelay;

        if ($this->triggerDelay < 0) {
            $this->triggerDelay = 0;
        }

        return $this;
    }
}
