<?php

namespace NoahVet\Reef\Application\Security\Service;

use NoahVet\Reef\Domain\Security\Policy\PolicyInterface;

/**
 * Holds the collection of all registered policies and provides filtered access.
 * Inject this service into use cases rather than the raw iterable.
 */
class PolicyOrchestrator implements PolicyOrchestratorInterface
{
    /**
     * @param iterable<PolicyInterface<object>> $policies
     */
    public function __construct(
        private readonly iterable $policies,
    ) {
    }

    /**
     * Returns all policies that can handle the given subject.
     *
     * @return list<PolicyInterface<object>>
     */
    #[\Override]
    public function getPoliciesFor(object $subject): array
    {
        $handlers = [];

        foreach ($this->policies as $policy) {
            if ($policy->canHandle($subject)) {
                $handlers[] = $policy;
            }
        }

        return $handlers;
    }

    /**
     * @return iterable<PolicyInterface<object>>
     */
    #[\Override]
    public function all(): iterable
    {
        return $this->policies;
    }
}
