<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\CRUD\Resolver;

use Doctrine\ORM\EntityManagerInterface;

/**
 * Class Resolver.
 */
class Resolver
{
    /**
     * The key to get the role necessary for the action.
     */
    final public const ROLE = 'role';

    /**
     * @deprecated
     */
    final public const ROLE_EDIT = 'role.edit';

    /**
     * @deprecated
     */
    final public const ROLE_VIEW = 'role.view';

    /**
     * @var array
     */
    protected $crudConfig;

    /**
     * @var EntityManagerInterface
     */
    protected $em;

    /**
     * @var \Symfony\Component\PropertyAccess\PropertyAccessor
     */
    protected $propertyAccess;

    /**
     * Resolver constructor.
     */
    public function __construct(EntityManagerInterface $em, array $crudConfig)
    {
        $this->em = $em;

        foreach ($crudConfig as $conf) {
            $this->crudConfig[$conf['name']] = $conf;
        }
    }

    /**
     * @return string
     */
    public function buildDefaultRole($crudName, $action)
    {
        if (empty($this->crudConfig[$crudName]['base_role'])) {
            throw new \LogicException(sprintf('the base role is not defined. You must define on or override %s or %s methods', __METHOD__, 'getRoleFor'));
        }

        return \strtoupper(
            $this->crudConfig[$crudName]['base_role'].
            '_'.
            $action
        );
    }

    /**
     * @param null $action
     *
     * @return string
     */
    public function getConfigValue($key, $crudName, $action = null)
    {
        $config = $this->crudConfig[$crudName];

        switch ($key) {
            case self::ROLE:
                return $config['actions'][$action]['role'] ?? $this->buildDefaultRole($crudName, $action);
        }
    }

    /**
     * @return bool
     */
    public function hasAction($crudName, $action)
    {
        return \array_key_exists(
            $action,
            $this->crudConfig[$crudName]['actions']
        );
    }
}
