<?php
declare(strict_types=1);

namespace App\Framework\ExceptionHandling;

use App\Framework\ExceptionHandling\Strategy\StrictErrorPolicy;
use ErrorException;

final readonly class ErrorHandler
{
    public function __construct(
        private ErrorHandlerStrategy $strategy = new StrictErrorPolicy,
    )
    {}


    /**
     * @throws ErrorException
     */
    public function handle(
        int $severity,
        string $message,
        ?string $file = null,
        ?int $line = null,
    ): bool {

        $context = ErrorContext::create(
            severity    : $severity,
            message     : $message,
            file        : $file,
            line        : $line,
            isSuppressed: $this->isSuppressed($severity)
        );

        $decision = $this->strategy->handle($context);

        return match($decision) {
            ErrorDecision::HANDLED => true,
            ErrorDecision::DEFER => false,
            ErrorDecision::THROW => throw new ErrorException($message, 0, $severity, $file, $line),
        };
    }

    private function isSuppressed($severity): bool
    {
        return !(error_reporting() & $severity);
    }
}
