<?php

namespace NoahVet\Reef\Security\Policy;

use NoahVet\Reef\Application\Security\UseCase\BatchSyncPoliciesUseCase;
use NoahVet\Reef\Application\Security\UseCase\BatchSyncPoliciesUseCaseInterface;
use NoahVet\Reef\Application\Security\UseCase\ExecutePoliciesUseCase;
use NoahVet\Reef\Application\Security\UseCase\ExecutePoliciesUseCaseInterface;
use NoahVet\Reef\Application\Security\UseCase\SyncPoliciesUseCase;
use NoahVet\Reef\Application\Security\UseCase\SyncPoliciesUseCaseInterface;
use NoahVet\Reef\Domain\Security\Port\PolicyResultPublisherInterface;

/**
 * @deprecated inject SyncPoliciesUseCase / BatchSyncPoliciesUseCase directly instead
 */
class PolicyManager
{
    protected SyncPoliciesUseCaseInterface $syncUseCase;

    protected BatchSyncPoliciesUseCaseInterface $batchSyncUseCase;

    protected ExecutePoliciesUseCaseInterface $executeUseCase;

    protected PolicyResultPublisherInterface $publisher;

    public function __construct(
        PolicyResultPublisherInterface $policyResultPublisher,
        SyncPoliciesUseCaseInterface $syncPoliciesUseCase,
        BatchSyncPoliciesUseCaseInterface $batchSyncPoliciesUseCase,
        ExecutePoliciesUseCase $executePoliciesUseCase,
    ) {
        $this->publisher = $policyResultPublisher;
        $this->syncUseCase = $syncPoliciesUseCase;
        $this->batchSyncUseCase = $batchSyncPoliciesUseCase;
        $this->executeUseCase = $executePoliciesUseCase;
    }

    /**
     * Forcefully compute all policies for a subject without syncing.
     *
     * @return list<\NoahVet\Reef\Domain\Security\Policy\PolicyResult>
     */
    public function executeAllPolicies(object $subject): array
    {
        return $this->executeUseCase->execute($subject);
    }

    /**
     * Ensure everything is synced with the IAM about this resource.
     *
     * @see batchSyncPolicies
     */
    public function syncPolicies(object $subject): void
    {
        $this->syncUseCase->sync($subject);
    }

    /**
     * Ensure everything is synced with the IAM about a list of resources.
     *
     * @param object[] $subjects
     */
    public function batchSyncPolicies(array $subjects): void
    {
        $this->batchSyncUseCase->batchSync($subjects);
    }

    public function syncPolicyResult(PolicyResult $result): void
    {
        $this->publisher->publish($result);
    }
}
