<?php


namespace App\Model\Facades\Writers;


use App\Model\Entities\Security\Rule;
use App\Model\Facades\Readers\PermissionReader;
use App\Model\Facades\Readers\SiteReader;
use App\Model\Facades\Readers\TemplateReader;
use App\Model\Interfaces\ICommonRecord;
use App\Model\Services\PermissionService;
use Throwable;

class PermissionWriter extends BaseWriter
{
    /** @var  PermissionService */
    protected $permissionService;
    /** @var  PermissionReader */
    protected $permissionReader;
    /** @var  TemplateReader */
    protected $templateReader;
    /** @var  SiteReader */
    protected $siteReader;

    public function inject(PermissionService $permissionService, PermissionReader $permissionReader, TemplateReader $templateReader, SiteReader $siteReader)
    {
        $this->permissionService = $permissionService;
        $this->permissionReader = $permissionReader;
        $this->templateReader = $templateReader;
        $this->siteReader = $siteReader;
    }

    public function createRole($name, $site = null, $parents = array(), $defaultRole = false)
    {
        if ($site !== null) {
            $site = $this->siteReader->validateSite($site);
        }
        if (!is_array($parents)) {
            $parents = [$parents];
        }

        try {
            $this->beginTransaction();
            $role = $this->permissionService->createRole($this->getLoggedInUser(), $site, $name, $parents);
            $role->setAsDefaultRole($defaultRole);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $role;
    }

    public function createWebmasterRole($name)
    {
        try {
            $this->beginTransaction();
            $role = $this->createRole($name);
            $role->setAsWebmasterRole(true);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $role;
    }

    public function createGuestRole()
    {
        return $this->createRole('guest');
    }

    public function addRule($role, $template, $action, $state = ICommonRecord::ACTIVE) : Rule
    {
        $roleEntity = $this->permissionReader->validateRole($role);
        $templateEntity = $this->templateReader->validateTemplate($template);

        try {
            $this->beginTransaction();
            $rule = $this->permissionService->createRule($roleEntity, $templateEntity, $action, $state);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $rule;
    }
}