<?php

namespace Velis\Acl;

use Velis\App;
use Velis\Arrays;
use Velis\Repository\UserRepository;
use Velis\Session\RedisSession;
use Velis\User;

class PrivsReloader
{
    use RedisSessionTrait;

    private $users = [];
    private $roles = [];

    /**
     * Add roles that should be included in privs reload
     *
     * @param string[]|string $roles Role ID or list of role ids
     * @return PrivsReloader $this
     */
    public function addRoles($roles)
    {
        if (!is_array($roles)) {
            $roles = [$roles];
        }

        array_push($this->roles, ...$roles);
        return $this;
    }

    /**
     * Add users that should be included in privs reload
     *
     * @param int[]|int $users User ID or list of user ids
     * @return PrivsReloader $this
     */
    public function addUsers($users)
    {
        if (!is_array($users)) {
            $users = [$users];
        }

        array_push($this->users, ...$users);
        return $this;
    }

    public function getUserIdsToReload()
    {
        $users = $this->users;
        if ($this->roles) {
            /** @var UserRepository */
            $repository = App::$di['db']->getRepository(User::class);
            $usersByRole = $repository->getIdsByRoles($this->roles);

            $users = array_merge($users, $usersByRole);
        }

        return $users;
    }

    public function reload()
    {
        if (App::$config->resque->enabled && in_array('acl', Arrays::toArray(App::$config->resque->workers))) {
            $this->queueReload();
        } else {
            /** @var RedisSession  */
            $session = $this->getSession();
            $users = User::instance($this->getUserIdsToReload(), false, ['user_id', 'node_token']);

            foreach ($users as $user) {
                $session->reloadPrivs($user);
            }
        }
    }

    private function queueReload()
    {
        /** @var QueueInterface $queue */
        $queue = App::$di->get('queue');

        $privsQueue = new PrivsQueue();
        $privsQueue->setParams([
            'user_id' => $this->getUserIdsToReload(),
        ]);

        $privsQueue->addToQueue($queue);
    }
}
