<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * File system error codes
 *
 * Covers file operations, permissions, and storage issues
 */
enum FileSystemErrorCode: string implements ErrorCode
{
    case FILE_NOT_FOUND = 'FS001';
    case PERMISSION_DENIED = 'FS002';
    case DISK_FULL = 'FS003';
    case READ_FAILED = 'FS004';
    case WRITE_FAILED = 'FS005';

    public function getValue(): string
    {
        return $this->value;
    }

    public function getCategory(): string
    {
        return 'FS';
    }

    public function getNumericCode(): int
    {
        return (int) substr($this->value, -3);
    }

    public function getSeverity(): ErrorSeverity
    {
        return match($this) {
            self::DISK_FULL => ErrorSeverity::CRITICAL,

            self::PERMISSION_DENIED,
            self::WRITE_FAILED => ErrorSeverity::ERROR,

            self::FILE_NOT_FOUND,
            self::READ_FAILED => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::FILE_NOT_FOUND => 'File or directory not found',
            self::PERMISSION_DENIED => 'File system permission denied',
            self::DISK_FULL => 'Disk storage is full',
            self::READ_FAILED => 'File read operation failed',
            self::WRITE_FAILED => 'File write operation failed',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::FILE_NOT_FOUND => 'Verify file path and existence',
            self::PERMISSION_DENIED => 'Check file permissions and ownership',
            self::DISK_FULL => 'Free up disk space or increase storage capacity',
            self::READ_FAILED => 'Check file integrity and permissions',
            self::WRITE_FAILED => 'Check disk space and write permissions',
        };
    }

    public function isRecoverable(): bool
    {
        return match($this) {
            self::FILE_NOT_FOUND => false,
            default => true,
        };
    }

    public function getRetryAfterSeconds(): ?int
    {
        return null;
    }
}
