<?php
/**
 * @package     DOCman
 * @copyright   Copyright (C) 2019 Timble CVBA. (http://www.timble.net)
 * @license     GNU GPLv3 <http://www.gnu.org/licenses/gpl.html>
 * @link        http://www.joomlatools.com
 */

namespace Foliolabs\Docman;

use Foliolabs\Library;

class ControllerBehaviorNotifiable extends Library\ControllerBehaviorAbstract
{
    protected function _initialize(Library\ObjectConfig $config)
    {
        $config->append(['suffix' => true, 'controller_map' => ['download' => 'document'], 'action_map' => ['compress' => 'download']]);

        parent::_initialize($config); // TODO: Change the autogenerated stub
    }

    protected function _beforeRender(Library\ControllerContextInterface $context)
    {
        // This if needed for the method below to kick in (TODO: check that out later)
    }

    public function execute(Library\CommandInterface $command, Library\CommandChainInterface $chain)
    {
        $parts = explode('.', $command->getName());

        if($parts[0] == 'after' && !in_array($parts[1], ['render', 'read', 'browse']))
        {
            $entities = $command->getEntity();

            if ($entities instanceof Library\ModelEntityInterface)
            {
                $action = $parts[1];

                if (isset($this->getConfig()->action_map[$action])) {
                    $action = $this->getConfig()->action_map[$action];
                }
                
                if ($this->getConfig()->suffix) {
                    $action = sprintf('%s%s', $action, $this->_getSuffix());
                }

                $jobs = [];

                foreach ($entities as $entity)
                {
                    if ($entity->isNotifiable())
                    {
                        $context = new NotifierContext($command->getName(), $command->getAttributes(), $command->getSubject());

                        $context->setEntity($entity);
                        $context->setActor($this->getMixer()->getUser());
                        $context->setAction($action);

                        foreach ($entity->getNotifications() as $notification)
                        {
                            if ($notification->hasAction($action))
                            {
                                $notifier = $notification->getNotifier();

                                if (($job = $notifier->getJob())) {
                                    $jobs[] = $job;
                                }

                                $notification->send($context);
                            } 
                        }
                    }
                }

                if ($jobs)
                {
                    $jobs = array_unique($jobs);

                    $dispatcher = $this->getObject('com:scheduler.controller.dispatcher');

                    $dispatcher->synchronize(); // Make sure jobs are set on scheduler 

                    foreach ($jobs as $job)
                    {
                        $context      = $dispatcher->getContext();
                        $context->job = $dispatcher->getModel()->id($job)->fetch();
                        
                        $dispatcher->dispatch($context); // Run jobs asynchronously to send small batches of notifications right away. 
                    }
                }
            }
        }

        return parent::execute($command, $chain);
    }

    protected function _getSuffix()
    {
        $controller = $this->getMixer()->getIdentifier()->getName();

        if (isset($this->getConfig()->controller_map[$controller])) {
            $controller = $this->getConfig()->controller_map[$controller];
        }

        return sprintf('_%s', $controller);
    }
}