<?php

namespace App\Model\Entities\Security;

use App\Model\Entities\BaseNamedRecord;
use App\Model\Interfaces\ISite;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/** @ORM\Entity */
class Role extends BaseNamedRecord
{
    const CREATED = 'created';
    const ACTIVE = 'active';
    const DELETED = 'deleted';

    /**
     * @ORM\Column(type="boolean")
     */
    protected $isWebmasterRole;

    /**
     * @var  ISite
     * @ORM\ManyToOne(targetEntity="App\Model\Entities\PortalSite")
     * @ORM\JoinColumn(nullable=true)
     */
    protected $site;

    /**
     * @var bool
     * @ORM\Column(type="boolean")
     */
    protected $defaultRole;

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
     * @var ArrayCollection
     */
    protected $users;

    /**
     * @ORM\ManyToMany(targetEntity="Role", mappedBy="childRoles")
     * @var ArrayCollection
     */
    protected $parentRoles;

    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="parentRoles")
     * @ORM\JoinTable(name="role_heredity",
     *      joinColumns={@ORM\JoinColumn(name="parent_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="child_id", referencedColumnName="id")}
     *      )
     */
    protected $childRoles;

    public function __construct(User $createdBy)
    {
        parent::__construct($createdBy);

        $this->users = new ArrayCollection();
        $this->parentRoles = new ArrayCollection();
        $this->childRoles = new ArrayCollection();
        $this->setAsWebmasterRole(false);
        $this->setState(self::CREATED);
    }

    /**
     * @return ISite
     */
    public function getSite()
    {
        return $this->site;
    }

    /**
     * @param ISite $site
     */
    public function setSite(ISite $site = null)
    {
        $this->site = $site;
    }

    /**
     * @return boolean
     */
    public function isDefaultRole() : bool
    {
        return $this->defaultRole;
    }

    /**
     * @param boolean $defaultRole
     */
    public function setAsDefaultRole(bool $defaultRole = true)
    {
        $this->defaultRole = $defaultRole;
    }

    /**
     * @return bool
     */
    public function isWebmasterRole() : bool
    {
        return $this->isWebmasterRole;
    }

    /**
     * @param bool $isWebmasterRole
     */
    public function setAsWebmasterRole(bool $isWebmasterRole = true)
    {
        $this->isWebmasterRole = $isWebmasterRole;
    }

    /**
     * @return ArrayCollection
     */
    public function getUsers()
    {
        return $this->users;
    }

    /**
     * @return ArrayCollection
     */
    public function getParentRoles()
    {
        return $this->parentRoles;
    }

    /**
     * @param Role $role
     */
    public function addParentRole(Role $role)
    {
        $this->parentRoles->add($role);

        $role->addChildRole($this);
    }

    /**
     * @param Role $role
     */
    public function removeParentRole(Role $role)
    {
        $this->parentRoles->remove($role);

        $role->removeChildRole($this);
    }

    /**
     * @return ArrayCollection
     */
    public function getChildRoles()
    {
        return $this->childRoles;
    }


    /**
     * @param Role $role
     */
    public function addChildRole(Role $role)
    {
        if (!$this->childRoles->contains($role)) {
            $this->childRoles->add($role);
        }
    }

    /**
     * @param Role $role
     */
    public function removeChildRole(Role $role)
    {
        $this->childRoles->remove($role);
    }

    protected function isValidState(string $state) : bool
    {
        return in_array($state, [self::CREATED, self::ACTIVE, self::DELETED]);
    }


}