<?php
namespace EasyChat\Library;








class SafeRuntime {
    public static function call(callable $callback, $fallback = false) {
        $handler = function () {
            return true;
        };
        set_error_handler($handler);
        try {
            return $callback();
        } catch (\Throwable $e) {
            return $fallback;
        } finally {
            restore_error_handler();
        }
    }

    public static function mkdir($dir, $mode = 0755, $recursive = true) {
        $dir = (string)$dir;
        if ($dir === '') {
            return false;
        }
        if (is_dir($dir)) {
            return true;
        }
        return (bool)self::call(function () use ($dir, $mode, $recursive) {
            return mkdir($dir, $mode, $recursive);
        }, false);
    }

    public static function chmod($path, $mode) {
        $path = (string)$path;
        if ($path === '' || !file_exists($path)) {
            return false;
        }
        return (bool)self::call(function () use ($path, $mode) {
            return chmod($path, $mode);
        }, false);
    }

    public static function permissions($path) {
        $path = (string)$path;
        if ($path === '' || !file_exists($path)) {
            return null;
        }
        $permissions = self::call(function () use ($path) {
            return fileperms($path);
        }, false);
        return $permissions === false ? null : ((int)$permissions & 0777);
    }

    public static function readFile($path) {
        $path = (string)$path;
        if ($path === '' || !is_file($path)) {
            return false;
        }
        return self::call(function () use ($path) {
            return file_get_contents($path);
        }, false);
    }

    public static function writeFile($path, $content, $flags = 0) {
        $path = (string)$path;
        if ($path === '') {
            return false;
        }
        $result = self::call(function () use ($path, $content, $flags) {
            return file_put_contents($path, $content, $flags);
        }, false);
        return $result !== false;
    }

    public static function writeFileAtomic($path, $content, $mode = 0640) {
        $path = (string)$path;
        $content = (string)$content;
        $directory = dirname($path);
        if ($path === '' || !is_dir($directory) || is_link($path) || is_dir($path)) {
            return false;
        }

        try {
            $temporary = $path . '.tmp.' . bin2hex(random_bytes(8));
        } catch (\Throwable $e) {
            return false;
        }

        return (bool)self::call(function () use ($temporary, $path, $content, $mode) {
             
             
            $previous_umask = umask(0077);
            try {
                $handle = fopen($temporary, 'x+b');
            } finally {
                umask($previous_umask);
            }
            if ($handle === false) {
                return false;
            }

            $offset = 0;
            $length = strlen($content);
            while ($offset < $length) {
                $written = fwrite($handle, substr($content, $offset));
                if ($written === false || $written === 0) {
                    break;
                }
                $offset += $written;
            }
            $flushed = fflush($handle);
            fclose($handle);

            $mode = ((int)$mode) & 0777;
            $valid = $offset === $length
                && $flushed
                && chmod($temporary, $mode)
                && is_file($temporary)
                && !is_link($temporary)
                && ((fileperms($temporary) & 0777) === $mode)
                && hash_equals(hash('sha256', $content), (string)hash_file('sha256', $temporary));
            if (!$valid || !rename($temporary, $path)) {
                if (is_file($temporary) || is_link($temporary)) {
                    unlink($temporary);
                }
                return false;
            }

            clearstatcache(true, $path);
            return is_file($path)
                && !is_link($path)
                && ((fileperms($path) & 0777) === $mode)
                && hash_equals(hash('sha256', $content), (string)hash_file('sha256', $path));
        }, false);
    }

    public static function rename($from, $to) {
        $from = (string)$from;
        $to = (string)$to;
        if ($from === '' || $to === '') {
            return false;
        }
        return (bool)self::call(function () use ($from, $to) {
            return rename($from, $to);
        }, false);
    }

    public static function unlink($path) {
        $path = (string)$path;
        if ($path === '' || (!is_file($path) && !is_link($path))) {
            return true;
        }
        return (bool)self::call(function () use ($path) {
            return unlink($path);
        }, false);
    }

    public static function rmdir($path) {
        $path = (string)$path;
        if ($path === '' || !is_dir($path)) {
            return true;
        }
        if (is_link($path)) {
            return false;
        }
        return (bool)self::call(function () use ($path) {
            return rmdir($path);
        }, false);
    }

    public static function imageInfo($path) {
        $path = (string)$path;
        if ($path === '' || !is_file($path)) {
            return false;
        }
        return self::call(function () use ($path) {
            return getimagesize($path);
        }, false);
    }
}
