<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonCommon\Classes\Installation\AclResource;

use Doctrine\ORM\EntityManager;
use Shopware\Models\User\Privilege;
use Shopware\Models\User\Resource;
use Shopware\Models\User\Rule;

class AclResourceHelper
{

    /**
     * @todo Change to `\Shopware\Models\User\Privilege::class` once we can depend on PHP >= 5.5.
     */
    const PRIVILEGE_CLASS = 'Shopware\\Models\\User\\Privilege';

    /**
     * @todo Change to `\Shopware\Models\User\Resource::class` once we can depend on PHP >= 5.5.
     */
    const RESOURCE_CLASS = 'Shopware\\Models\\User\\Resource';

    /**
     * @todo Change to `\Shopware\Models\User\Rule::class` once we can depend on PHP >= 5.5.
     */
    const RULE_CLASS = 'Shopware\\Models\\User\\Rule';

    /**
     * @var EntityManager
     */
    private $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * @return Resource|null
     */
    public function findResourceByName($resourceName)
    {
        return $this->entityManager->getRepository(static::RESOURCE_CLASS)->findOneBy([
            'name' => $resourceName,
        ]);
    }

    /**
     * @param array<Privilege> $oldPrivileges
     * @return array<Rule>
     */
    public function findRulesForPrivileges(array $privileges, $resourceId)
    {
        $privilegeIds = array_map(function (Privilege $p) {
            return $p->getId();
        }, $privileges);
        /* @var $rules array<Rule> */
        $rules = $this->entityManager->createQueryBuilder()
            ->select('r')->from(static::RULE_CLASS, 'r')
            ->where('r.privilegeId in (:privilegeIds)') // FIXME: might not be necessary
            ->orWhere('r.resourceId = :resourceId')
            ->setParameter('privilegeIds', $privilegeIds)
            ->setParameter('resourceId', $resourceId)
            ->getQuery()
            ->getResult();

        return $rules;
    }

    /**
     * @return array<Privilege>
     */
    public function findPrivilegesByResourceId($resourceId)
    {
        return $this->entityManager->getRepository(static::PRIVILEGE_CLASS)->findBy([
            'resourceId' => $resourceId,
        ]);
    }
}
