<?php
namespace EasyChat\Library\Support;

use EasyChat\Library\SafeRuntime;




class LogTailReader {
    public const DEFAULT_MAX_LINES = 150;
    public const DEFAULT_MAX_BYTES = 262144;
    private const CHUNK_BYTES = 8192;

    


    public function read($path, $maxLines = self::DEFAULT_MAX_LINES, $maxBytes = self::DEFAULT_MAX_BYTES) {
        $path = (string)$path;
        $maxLines = max(1, min(1000, (int)$maxLines));
        $maxBytes = max(4096, min(1048576, (int)$maxBytes));

        if ($path === '' || !is_file($path)) {
            return null;
        }

        return SafeRuntime::call(function () use ($path, $maxLines, $maxBytes) {
            $handle = fopen($path, 'rb');
            if ($handle === false) {
                return null;
            }

            try {
                $stat = fstat($handle);
                $size = is_array($stat) ? (int)($stat['size'] ?? 0) : 0;
                if ($size <= 0) {
                    return '';
                }

                $position = $size;
                $remainingBytes = min($size, $maxBytes);
                $newlineCount = 0;
                $buffer = '';

                while ($position > 0 && $remainingBytes > 0 && $newlineCount <= $maxLines) {
                    $readBytes = min(self::CHUNK_BYTES, $position, $remainingBytes);
                    $position -= $readBytes;
                    if (fseek($handle, $position, SEEK_SET) !== 0) {
                        return null;
                    }

                    $chunk = fread($handle, $readBytes);
                    if ($chunk === false) {
                        return null;
                    }
                    if ($chunk === '') {
                        break;
                    }

                    $buffer = $chunk . $buffer;
                    $remainingBytes -= strlen($chunk);
                    $newlineCount += substr_count($chunk, "\n");
                }

                $byteLimitReached = $position > 0 && $remainingBytes <= 0 && $newlineCount <= $maxLines;

                 
                 
                if ($position > 0) {
                    $firstLineEnd = strpos($buffer, "\n");
                    if ($firstLineEnd !== false) {
                        $buffer = substr($buffer, $firstLineEnd + 1);
                    }
                }

                $lines = preg_split('/(?<=\n)/', $buffer, -1, PREG_SPLIT_NO_EMPTY);
                if (!is_array($lines)) {
                    return null;
                }

                $content = implode('', array_slice($lines, -$maxLines));
                if ($byteLimitReached) {
                    $content = "[Показан только конец большого лога]\n" . ltrim($content, "\r\n");
                }

                return $content;
            } finally {
                fclose($handle);
            }
        }, null);
    }
}
