'Copyright Luke Ceddia
'SPDX-License-Identifier: Apache-2.0
'tempfile.bm - Manage temporary files

$if WINDOWS then
declare customtype library
    function GetTempPath&(byval s_len&, byval s%&)
end declare

'This function is incorrect because it separately tests for the non-existence
'of the temp file, then opens it.
function ll_write_tempfile$ (extension$, buf as _offset, buf_len&&)
    chars$ = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
    dim mem as _mem
    dir_len = GetTempPath(0, 0)
    if dir_len = 0 then fatalerror "Cannot determine temp directory"
    mem = _memnew(dir_len + 1)
    ret = GetTempPath(dir_len + 1, mem.offset)
    if ret = 0 then fatalerror "Cannot determine temp directory"
    dir$ = space$(dir_len)
    _memget mem, mem.offset, dir$
    _memfree mem
    if asc(right$(dir$, 1)) = 0 then dir$ = left$(dir$, len(dir$) - 1)
    for i = 1 to 1000
        nam$ = ""
        for j = 1 to 6
            nam$ = nam$ + mid$(chars$, int(rnd * len(chars$)) + 1, 1)
        next j
        path$ = dir$ + nam$ + extension$
        if not _fileexists(path$) then
            fh = freefile
            open path$ for binary as #fh
            mem = _mem(buf, buf_len&&)
            content$ = space$(buf_len&&)
            _memget mem, mem.offset, content$
            put #fh, , content$
            close #fh
            ll_write_tempfile$ = path$
            exit function
        end if
    next i
    fatalerror "Cannot create temp file"
end function

$else

declare customtype library
    function mkstemps&(template$, byval suffixlen&)
    function c_write&& alias write(byval fd&, byval buf%&, byval count&&)
    function c_close& alias close(byval fd&)
end declare

function ll_write_tempfile$(extension$, buf as _offset, buflen&&)
    dir$ = environ$("TMPDIR")
    if dir$ = "" then dir$ = "/tmp"
    template$ = dir$ + "/XXXXXX" + extension$ + chr$(0)
    fd = mkstemps&(template$, len(extension$))
    if fd = -1 then fatalerror "Cannot create temp file"
    ' mkstemps modifies the XXXXXX to be the actual value
    filename$ = left$(template$, len(template$) - 1)
    ret1&& = c_write&&(fd, buf, buflen&&)
    if ret1&& < buflen&& then fatalerror "Cannot write temp file"
    ret2 = c_close&(fd)
    if ret2 = -1 then fatalerror "Cannot write temp file"
    ll_write_tempfile$ = filename$
end function
$end if
