<?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\CalendarBundle\Security\Voter;

use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Entity\CalendarDoc;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Exception\LogicException;
use Symfony\Component\Security\Core\Security;

class CalendarDocVoter extends Voter
{
    final public const EDIT = 'CHILL_CALENDAR_DOC_EDIT';

    final public const SEE = 'CHILL_CALENDAR_DOC_SEE';

    private const ALL = [
        'CHILL_CALENDAR_DOC_EDIT',
        'CHILL_CALENDAR_DOC_SEE',
    ];

    public function __construct(private readonly Security $security) {}

    protected function supports($attribute, $subject): bool
    {
        return \in_array($attribute, self::ALL, true) && ($subject instanceof CalendarDoc || $subject instanceof Calendar);
    }

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
    {
        if ($subject instanceof Calendar) {
            return match ($attribute) {
                self::EDIT => $this->security->isGranted(CalendarVoter::EDIT, $subject),
                self::SEE => $this->security->isGranted(CalendarVoter::SEE, $subject),
                default => throw new LogicException('attribute not supported for this Voter'),
            };
        } elseif ($subject instanceof CalendarDoc) {
            return match ($attribute) {
                self::EDIT => $this->security->isGranted(CalendarVoter::EDIT, $subject->getCalendar()),
                self::SEE => $this->security->isGranted(CalendarVoter::SEE, $subject->getCalendar()),
                default => throw new \UnexpectedValueException('Attribute not supported: '.$attribute),
            };
        }

        throw new LogicException('Subject not supported for this Voter');
    }
}
