<?php

	namespace Icing\Policy;

	use Authorization\IdentityInterface;
	use Cake\ORM\Locator\LocatorAwareTrait;
	use Cake\ORM\Query;
    use Cake\ORM\Table;
    use Icing\Model\Entity\User;
    use Icing\Model\Table\PermissionsTable;
    use InvalidArgumentException;

    class IcingPermissionsPolicy
	{

		use LocatorAwareTrait;

		private PermissionsTable|Table $Permissions;

		public function __construct()
		{
			$this->Permissions = $this->fetchTable('Icing.Permissions');
		}

		public function __call(string $name, array $arguments)
		{
			/** @var IdentityInterface $user */
			[$user, $permission] = $arguments;

			if (!is_string($permission)) {
				throw new InvalidArgumentException('Permission should be a string value');
			}

			if (!$user instanceof User) {
				return false;
			}

			$permission = $this->Permissions->findOrCreate($permission);

			// Special permissions granted to admins
			if ($user->is('admin')) {
				return true;
			}

			return (bool)$this->Permissions->find()
				->where(['Permissions.id' => $permission->id])
				->matching('Roles.UserGroups', fn(Query $q) => $q->where(['UserGroups.id' => $user->user_group_id]))
				->first();
		}
	}

