<?php

declare(strict_types=1);

namespace Flowaxy\Infrastructure\Security;

use Flowaxy\Contracts\Security\PluginCapabilityInterface;
use Flowaxy\Infrastructure\Persistence\Repositories\PluginCapabilityRepository;
use Flowaxy\Support\Facades\Log;
use Throwable;

/**
 * Guard для проверки capabilities в runtime
 *
 * @package Flowaxy\Infrastructure\Security
 */
final class PluginCapabilityChecker implements PluginCapabilityInterface
{
    public function __construct(
        private readonly PluginCapabilityRepository $repository
    ) {
    }

    /**
     * Проверить, имеет ли плагин capability
     *
     * @param string $pluginSlug Slug плагина
     * @param string $capability Название capability
     * @return bool
     */
    public function hasCapability(string $pluginSlug, string $capability): bool
    {
        return $this->repository->hasCapability($pluginSlug, $capability);
    }

    /**
     * Получить все granted capabilities для плагина
     *
     * @param string $pluginSlug Slug плагина
     * @return array<int, string>
     */
    public function getGrantedCapabilities(string $pluginSlug): array
    {
        return $this->repository->getGrantedCapabilities($pluginSlug);
    }

    /**
     * Предоставить capability плагину
     *
     * @param string $pluginSlug Slug плагина
     * @param string $capability Название capability
     * @return bool
     */
    public function grantCapability(string $pluginSlug, string $capability): bool
    {
        try {
            return $this->repository->grantCapability($pluginSlug, $capability);
        } catch (Throwable $e) {
            try {
                Log::Error('Ошибка предоставления capability', [
                    'plugin_slug' => $pluginSlug,
                    'capability' => $capability,
                    'exception' => $e,
                ]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }

    /**
     * Отозвать capability у плагина
     *
     * @param string $pluginSlug Slug плагина
     * @param string $capability Название capability
     * @return bool
     */
    public function revokeCapability(string $pluginSlug, string $capability): bool
    {
        try {
            return $this->repository->revokeCapability($pluginSlug, $capability);
        } catch (Throwable $e) {
            try {
                Log::Error('Ошибка отзыва capability', [
                    'plugin_slug' => $pluginSlug,
                    'capability' => $capability,
                    'exception' => $e,
                ]);
            } catch (Throwable $logError) {
                // Ignore logging errors
            }
            return false;
        }
    }
}
