<?php declare(strict_types = 1);

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

use idoit\Module\SyneticsFlows\Automation\Action\ActionType\ActionType;
use idoit\Module\SyneticsFlows\Automation\Action\ActionType\CmdbChange\CurrentObjectScope;
use idoit\Module\SyneticsFlows\Automation\Action\ActionType\CmdbChange\ObjectIdsScope;
use idoit\Module\SyneticsFlows\Automation\Action\ActionType\RankObjectAction;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionInfo\ExecutionInfo;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionInfo\RankObjectInfo;
use idoit\Module\SyneticsFlows\Automation\Automation;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\Invocation;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\ObjectContext;

class RankObjectFactory implements ExecutionFactory
{
    /**
     * @param Invocation $invocation
     * @param Automation $automation
     * @param ActionType $actionType
     *
     * @return ExecutionInfo|null
     */
    public function createExecution(Invocation $invocation, Automation $automation, ActionType $actionType): ?ExecutionInfo
    {
        if (!$actionType instanceof RankObjectAction) {
            return null;
        }

        return new RankObjectInfo($actionType->getStatus(), $this->getObjectIds($actionType, $invocation));
    }

    /**
     * @param RankObjectAction $action
     *
     * @param Invocation $invocation
     *
     * @return array
     */
    private function getObjectIds(RankObjectAction $action, Invocation $invocation): array
    {
        $scope = $action->getScope();

        if ($scope instanceof CurrentObjectScope) {
            $context = $invocation->getContext();

            if ($context instanceof ObjectContext) {
                return [$context->getObjectId()];
            }
        }

        if ($scope instanceof ObjectIdsScope) {
            return $scope->getIds();
        }

        return [];
    }

    /**
     * @param ActionType $actionType
     *
     * @return bool
     */
    public function supports(ActionType $actionType): bool
    {
        return $actionType instanceof RankObjectAction;
    }
}
