<?php


class RbacAccessService
{
    private static $skipAnnotation = '@rbacSkipControllerCheck';
    private static $aliasAnnotation = '@rbacAlias';

    public static function isActionAllowed($alias, array $permissions)
    {
        $allowedAliases = [];
        foreach ($permissions as $permission) {
            $allowedAliases[] = $permission['alias'];
        }

        /**
         * Return false if a method has rbacAlias annotation and a role doesn't have this permission
         * If method doesn't have rbacAlias annotation then every role can access this method
         */
        if (!empty($alias) && !in_array($alias, $allowedAliases)) {
            return false;
        }

        return true;
    }

    public static function isControllerAllowed($class, $method, array $permissions)
    {
        if (self::parseAnnotation($class, $method, self::$skipAnnotation) !== false) {
            return true;
        }

        $alias = self::parseAnnotation($class, $method, self::$aliasAnnotation);

        return self::isActionAllowed($alias, $permissions);
    }

    private static function parseAnnotation($class, $method, $annotation)
    {
        $reflectionMethod = new ReflectionMethod($class, $method);
        $methodComment = $reflectionMethod->getDocComment();
        $matches = [];
        preg_match('/'. $annotation .'(.*?)\*/s', $methodComment, $matches);
        return isset($matches[1]) ? trim($matches[1]) : false;
    }

}
