<?php

namespace App\Security\Voter\Tools;

use App\Entity\User;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

abstract class VoterInterface extends Voter
{
    public User $user;
    public array $userpermissions;
    public ?string $permissionsPrefix;

    public function __construct()
    {
        $this->setPermissionsPrefix(null);
    }

    public function setPermissionsPrefix(?string $prefix)
    {
        $this->permissionsPrefix = $prefix;
    }

    public function getPermissionsPrefix(): ?string
    {
        return $this->permissionsPrefix;
    }

    public function checkUser(User $User)
    {
        $this->user = $User;
        // if the user is anonymous, do not grant access
        if (!$this->user instanceof UserInterface) {
            return false;
        }

        // if the user has no group or no rank, do not grant access
        if ($this->user->getMainGroup() == null) {
            return false;
        }
        if ($this->user->getMainRank() == null) {
            return false;
        }

        //if user is in admin mode, bypass
        if ($this->user->getAdminMode()) {
            return true;
        }

        $this->userpermissions = $this->user->getMainRank()->getPermissions();

        //if user (rank) has no permissions, do not grant access
        if ($this->userpermissions == null) {
            return false;
        }

        return true;
    }

    /**
     * Check if user has the permission
     *
     * @param string $attribute
     * @param boolean $ignoreprefix
     * @return boolean
     */
    public function hasPermission(string $attribute, bool $ignoreprefix = false): bool
    {
        //if user is in admin mode, bypass
        if ($this->user->getAdminMode()) {
            return true;
        }

        $permission = strtolower(
            (
                $this->getPermissionsPrefix() != null
                && !$ignoreprefix ?
                $this->getPermissionsPrefix() . '_' : ''
            ) . $attribute
        );



        if (in_array($permission, array_map('strtolower', $this->userpermissions))) {
            return true;
        }
        return false;
    }

    /**
     * Determines if the attribute and subject are supported by this voter.
     *
     * @param string $attribute An attribute
     * @param mixed  $subject   The subject to secure, e.g. an object the user wants to access or any other PHP type
     *
     * @return bool True if the attribute and subject are supported, false otherwise
     */
    abstract protected function supports(string $attribute, $subject);
}
