<?php declare(strict_types = 1);

namespace idoit\Module\SyneticsFlows\Automation\Action\PerformExecution;

use idoit\Module\SyneticsFlows\Automation\Action\ExecutionFactory\ExecutionFactory;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionInfo\PlannedExecutionInfo;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionResult\ErrorExecutionResult;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionResult\ExecutionResult;
use idoit\Module\SyneticsFlows\Automation\Execution;
use idoit\Module\SyneticsFlows\Model\AutomationDao;

class PlannedExecution implements PerformExecution
{
    public function __construct(
        private AutomationDao $dao,
        private ExecutionFactory $factory,
        private PerformExecution $execution,
    )
    {
    }

    public function perform(Execution $execution): ExecutionResult
    {
        $executionInfo = $execution->getExecution();

        if (!$executionInfo instanceof PlannedExecutionInfo) {
            return new ErrorExecutionResult('Incorrect execution');
        }

        $flow = $this->dao->get($execution->getFlowId());

        if (!$flow) {
            return new ErrorExecutionResult('Cannot find flow with id ' . $execution->getFlowId());
        }

        $executionInfo = $this->factory->createExecution($execution->getInvocation(), $flow, $executionInfo->getActionType());

        if (!$executionInfo) {
            return new ErrorExecutionResult('Cannot create execution');
        }

        $execution->setExecution($executionInfo);

        return $this->execution->perform($execution);
    }

    public function supports(Execution $execution): bool
    {
        return $execution->getExecution() instanceof PlannedExecutionInfo;
    }
}