<?php

namespace App\Classes\Modules\Rules\Services;

use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\General\Interfaces\DataTransferObject;
use App\Classes\Exceptions\AccessForbiddenException;
use App\Classes\Exceptions\CriteriaNotFulfilledException;
use App\Classes\Exceptions\RequestValidationException;
use App\Classes\ValueObjects\Response\RuleEvaluationResult;

class RuleEvaluator //For using AbstractRule
{
    /**
     * Evaluate multiple rules.
     *
     * @param AbstractRule[] $rules
     * @param DataTransferObject|null $object
     * @return RuleEvaluationResult
     */
    public function evaluate(array $rules, ?DataTransferObject $object = null): RuleEvaluationResult
    {
        $messages = [];
        $success = true;

        foreach ($rules as $rule) {
            try {
                if (!$rule->passes($object)) {
                    $success = false;
                    $messages[] = get_class($rule) . ' failed without exception';
                }
            } catch (AccessForbiddenException | RequestValidationException | CriteriaNotFulfilledException $e) {
                $success = false;
                $messages[] = $e->getMessage();
            } catch (\Exception $e) {
                $success = false;
                $messages[] = 'Unexpected error in ' . get_class($rule) . ': ' . $e->getMessage();
            }
        }

        return new RuleEvaluationResult($success, $messages);
    }

}
