local fs={}

-- "VFS_open" : open
-- "VFS_read" : read
-- "VFS_write" : write
-- "VFS_close" : close

function fs.open(path, mode)
    local fd=syscall.VFS_open(path,mode)
    local ret={
        close=function()
            -- close file
            return syscall.VFS_close(fd)
        end,
        flush=function()
            -- close and reopen file to flush buffers
            syscall.VFS_close(fd)
            fd=syscall.VFS_open(path,mode)
        end
    }
    if mode=="r" then
        ret.read=function(count)
            local data = syscall.VFS_read(fd,count)
            return data
        end
        ret.readAll=function(chunkSize)
            local chunks={} -- to store read chunks
            while true do
                local chunk=syscall.VFS_read(fd,chunkSize or 65536)
                if chunk==nil or #chunk==0 then break end
                table.insert(chunks,chunk)
            end
            return table.concat(chunks)
        end
        ret.readLine = function(chunkSize)
            local buffer = {}                -- stores leftover data
            local buffer_str = ""            -- concatenated buffer
            local chunk_size = chunkSize or 65536          -- adjust chunk size for performance
            local eof = false

            while true do
                -- Try to find a newline in the current buffer
                local line_end = buffer_str:find("\n")
                if line_end then
                    local line = buffer_str:sub(1, line_end - 1)
                    buffer_str = buffer_str:sub(line_end + 1)
                    return line
                end
            
                -- If EOF was reached previously and buffer is empty, stop
                if eof then
                    if buffer_str ~= "" then
                        local last_line = buffer_str
                        buffer_str = ""
                        return last_line
                    else
                        return nil
                    end
                end
            
                -- Read the next chunk
                local chunk = syscall.VFS_read(fd, chunk_size)
                if not chunk or chunk == "" then
                    eof = true
                else
                    buffer_str = buffer_str .. chunk
                end
            end
        end
    elseif mode=="w" then
        ret.write=function(data)
            -- write data to file
            return syscall.VFS_write(fd,data)
        end
    elseif mode=="a" then
        ret.write=function(data)
            -- append data to file
            return syscall.VFS_write(fd,data)
        end
    else
        error("Invalid mode '"..mode.."'",2)
    end
    return ret
end

function fs.readAllText(path)
    local file=fs.open(path,"r")
    if not file then return false end
    local content=file.readAll()
    file.close()
    return content
end

function fs.writeAllText(path, data)
    local file=fs.open(path,"w")
    file.write(data)
    file.close()
end

function fs.appendAllText(path, data)
    local file=fs.open(path,"a")
    if not file then return false end
    file.write(data)
    file.close()
end

function fs.mkdir(path)
    return syscall.VFS_mkdir(path)
end

function fs.remove(path)
    return syscall.VFS_remove(path)
end

function fs.list(path)
    return syscall.VFS_list(path)
end

function fs.type(path)
    return syscall.VFS_type(path)
end

function fs.attributes(path)
    return syscall.VFS_attributes(path)
end

function fs.exists(path)
    return syscall.VFS_exists(path)
end

function fs.getcwd()
    return syscall.VFS_getcwd()
end

function fs.setcwd(path)
    return syscall.VFS_setcwd(path)
end

return fs