<?php

declare(strict_types=1);

namespace App\Application\Security\Events\Authorization;

use App\Application\Security\ValueObjects\{OWASPEventIdentifier, OWASPLogLevel};

final class AccessDeniedEvent
{
    public function __construct(
        public readonly string $email,
        public readonly string $resource,
        public readonly string $action,
        public readonly ?string $requiredPermission = null
    ) {
    }

    public function getOWASPEventIdentifier(): OWASPEventIdentifier
    {
        return OWASPEventIdentifier::authorizationFailure(
            $this->maskEmail($this->email),
            $this->resource
        );
    }

    public function getOWASPLogLevel(): OWASPLogLevel
    {
        return OWASPLogLevel::WARN;
    }

    public function getDescription(): string
    {
        return "Access denied for user {$this->maskEmail($this->email)} to resource {$this->resource}";
    }

    public function getEventData(): array
    {
        return [
            'username' => $this->maskEmail($this->email),
            'resource' => $this->resource,
            'action' => $this->action,
            'required_permission' => $this->requiredPermission,
        ];
    }

    private function maskEmail(string $email): string
    {
        if (! filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return $email;
        }

        [$local, $domain] = explode('@', $email, 2);
        $maskedLocal = substr($local, 0, 2) . str_repeat('*', max(0, strlen($local) - 2));

        return $maskedLocal . '@' . $domain;
    }
}
