<?php

namespace App\Model\Services;


use App\Model\Entities\Security\Role;
use App\Model\Entities\Security\Rule;
use App\Model\Entities\Security\User;
use App\Model\Interfaces\ISite;
use App\Model\Interfaces\ITemplate;

class PermissionService extends BaseService
{

    /**
     * @param $id
     * @return null|Role
     */
    public function findRoleById($id)
    {
        return $this->getRepository(Role::class)->find($id);
    }

    /**
     * @return null|Role
     */
    public function getWebmasterRole()
    {
        return  $this->getRepository(Role::class)->findOneBy(array('isWebmasterRole' => true));
    }

    /**
     * @return null|Role
     */
    public function getGuestRole()
    {
        return  $this->getRepository(Role::class)->findOneBy(array('name' => 'guest'));
    }

    /**
     * @return array
     */
    public function findAllRoles()
    {
        return $this->getRepository(Role::class)->findAll();
    }

    public function createRole(User $createdBy, ISite $site = null, $name, array $parents = array())
    {
        $role = new Role($createdBy);
        $role->setName($name);
        $role->setSite($site);

        foreach($parents as $parentRole) {
            $role->addParentRole($parentRole);
        }

        // todo: attach to entity onSave
//         webmaster nad guest are special global roles
//        if (($role->getName() !== 'guest' || !$role->isWebmasterRole()) && $role->getSite() === null) {
//            throw new RoleNotAttachedToSiteException();
//        }

        $this->persist($role);
        return $role;
    }

    /**
     * @param Role $role
     * @param ITemplate $template
     * @param $action
     * @param string $state
     * @param bool $isAppliedToOwner
     * @param bool $type
     * @return Rule
     */
    public function createRule(Role $role, ITemplate $template, $action, $state, $isAppliedToOwner = false, $type = Rule::ALLOW)
    {
        $rule = new Rule($type);
        $rule->setRole($role);
        $rule->setState($state);
        $rule->setAction($action);
        $rule->setTemplate($template);
        $rule->applyToOwner($isAppliedToOwner);

        $this->persist($rule);
        return $rule;
    }

    public function findRules(ITemplate $resource, $state)
    {
        $criteria = array(
            'template' => $resource,
            'state' => $state
        );
        return $this->getRepository(Rule::class)->findBy($criteria);
    }

    public function findSiteDefaultRole(ISite $site)
    {
        $criteria = [
            'site' => $site,
            'defaultRole' => true
        ];

        return $this->getRepository(Role::class)->findOneBy($criteria);
    }
}