<?php

declare(strict_types=1);

namespace App\Framework\Filesystem;

use App\Framework\Core\ValueObjects\Byte;
use InvalidArgumentException;

/**
 * Stream Writer
 *
 * Type-safe Wrapper für Stream-basierte File Operations.
 * Nutzt Framework's Byte Value Object für Buffer-Management.
 */
final class StreamWriter
{
    /**
     * @param resource $stream File stream resource
     */
    public function __construct(
        private $stream
    ) {
        if (!is_resource($stream)) {
            throw new InvalidArgumentException('Invalid stream resource');
        }
    }

    /**
     * Read data from stream
     *
     * @param Byte $length Number of bytes to read
     * @return string Read data
     * @throws InvalidArgumentException If read fails
     */
    public function read(Byte $length): string
    {
        $data = @fread($this->stream, $length->toBytes());

        if ($data === false) {
            throw new InvalidArgumentException('Failed to read from stream');
        }

        return $data;
    }

    /**
     * Write data to stream
     *
     * @param string $data Data to write
     * @return Byte Number of bytes written
     * @throws InvalidArgumentException If write fails
     */
    public function write(string $data): Byte
    {
        $bytesWritten = @fwrite($this->stream, $data);

        if ($bytesWritten === false) {
            throw new InvalidArgumentException('Failed to write to stream');
        }

        return Byte::fromBytes($bytesWritten);
    }

    /**
     * Check if end of stream reached
     */
    public function isEof(): bool
    {
        return feof($this->stream);
    }

    /**
     * Close stream
     */
    public function close(): void
    {
        if (is_resource($this->stream)) {
            fclose($this->stream);
        }
    }

    /**
     * Get underlying stream resource
     *
     * @return resource
     */
    public function getResource()
    {
        return $this->stream;
    }
}
