<?php

declare(strict_types=1);

namespace App\Framework\Filesystem\ValueObjects;

/**
 * Value Object für typsichere Filesystem-Operationen
 *
 * Repräsentiert verschiedene Filesystem-Operationen als Enum-ähnliches Value Object
 * für bessere Type Safety und explizite Operation-Deklaration
 */
enum FileOperation: string
{
    case READ = 'read';
    case WRITE = 'write';
    case DELETE = 'delete';
    case COPY = 'copy';
    case MOVE = 'move';
    case APPEND = 'append';
    case PREPEND = 'prepend';
    case CREATE_DIRECTORY = 'create_directory';
    case DELETE_DIRECTORY = 'delete_directory';
    case LIST_DIRECTORY = 'list_directory';
    case GET_METADATA = 'get_metadata';
    case CHECK_EXISTS = 'check_exists';
    case GET_SIZE = 'get_size';
    case GET_LAST_MODIFIED = 'get_last_modified';
    case READ_STREAM = 'read_stream';
    case WRITE_STREAM = 'write_stream';

    /**
     * Prüft ob Operation schreibend ist
     */
    public function isWriteOperation(): bool
    {
        return match ($this) {
            self::WRITE,
            self::DELETE,
            self::MOVE,
            self::APPEND,
            self::PREPEND,
            self::CREATE_DIRECTORY,
            self::DELETE_DIRECTORY,
            self::WRITE_STREAM => true,
            default => false
        };
    }

    /**
     * Prüft ob Operation lesend ist
     */
    public function isReadOperation(): bool
    {
        return match ($this) {
            self::READ,
            self::LIST_DIRECTORY,
            self::GET_METADATA,
            self::CHECK_EXISTS,
            self::GET_SIZE,
            self::GET_LAST_MODIFIED,
            self::READ_STREAM => true,
            default => false
        };
    }

    /**
     * Prüft ob Operation ein Directory betrifft
     */
    public function isDirectoryOperation(): bool
    {
        return match ($this) {
            self::CREATE_DIRECTORY,
            self::DELETE_DIRECTORY,
            self::LIST_DIRECTORY => true,
            default => false
        };
    }

    /**
     * Prüft ob Operation Stream-basiert ist
     */
    public function isStreamOperation(): bool
    {
        return match ($this) {
            self::READ_STREAM,
            self::WRITE_STREAM => true,
            default => false
        };
    }

    /**
     * Gibt erforderliche Permissions für Operation zurück
     */
    public function getRequiredPermissions(): int
    {
        return match ($this) {
            self::READ,
            self::LIST_DIRECTORY,
            self::GET_METADATA,
            self::CHECK_EXISTS,
            self::GET_SIZE,
            self::GET_LAST_MODIFIED,
            self::READ_STREAM => 0444, // Read permission
            self::WRITE,
            self::APPEND,
            self::PREPEND,
            self::WRITE_STREAM => 0644, // Read + Write permission
            self::DELETE,
            self::DELETE_DIRECTORY => 0200, // Write permission
            self::COPY,
            self::MOVE,
            self::CREATE_DIRECTORY => 0755, // Full permission
        };
    }

    /**
     * Gibt Operation-Name für Logging/Monitoring zurück
     */
    public function toOperationName(): string
    {
        return 'file.' . $this->value;
    }

    /**
     * Gibt human-readable Beschreibung zurück
     */
    public function getDescription(): string
    {
        return match ($this) {
            self::READ => 'Read file contents',
            self::WRITE => 'Write file contents',
            self::DELETE => 'Delete file',
            self::COPY => 'Copy file',
            self::MOVE => 'Move file',
            self::APPEND => 'Append to file',
            self::PREPEND => 'Prepend to file',
            self::CREATE_DIRECTORY => 'Create directory',
            self::DELETE_DIRECTORY => 'Delete directory',
            self::LIST_DIRECTORY => 'List directory contents',
            self::GET_METADATA => 'Get file metadata',
            self::CHECK_EXISTS => 'Check file existence',
            self::GET_SIZE => 'Get file size',
            self::GET_LAST_MODIFIED => 'Get last modified time',
            self::READ_STREAM => 'Read file as stream',
            self::WRITE_STREAM => 'Write file from stream',
        };
    }

    /**
     * Gibt Severity-Level für Operation zurück (für Monitoring/Logging)
     */
    public function getSeverity(): string
    {
        return match ($this) {
            self::DELETE,
            self::DELETE_DIRECTORY,
            self::MOVE => 'high',
            self::WRITE,
            self::COPY,
            self::CREATE_DIRECTORY => 'medium',
            default => 'low'
        };
    }

    /**
     * Prüft ob Operation reversibel ist
     */
    public function isReversible(): bool
    {
        return match ($this) {
            self::WRITE,
            self::APPEND,
            self::PREPEND,
            self::CREATE_DIRECTORY => true,
            self::DELETE,
            self::DELETE_DIRECTORY,
            self::MOVE => false,
            default => true
        };
    }
}
