// Amiga save-file + disk-space HAL.
//
// SAVES/ is a real directory next to the executable, made with dos.library
// CreateDir; delete is DeleteFile; free space is Info() on a lock to PROGDIR:
// (the program's -- and thus SAVES/'s -- volume). All ROM-backed, so no libc
// filesystem dependency.

#include <exec/types.h>
#include <dos/dos.h>

#include <proto/dos.h>

#include "joey/file.h"
#include "port.h"


#define AMIGA_MAX_U32   0xFFFFFFFFu


uint32_t jlpDiskFree(void) {
    struct InfoData  info;
    BPTR             lock;
    uint32_t         freeBlocks;
    uint32_t         bytesPerBlock;

    lock = Lock((CONST_STRPTR)"PROGDIR:", SHARED_LOCK);
    if (lock == 0) {
        return 0u;
    }
    if (Info(lock, &info) == 0) {
        UnLock(lock);
        return 0u;
    }
    UnLock(lock);

    freeBlocks = (info.id_NumBlocks > info.id_NumBlocksUsed)
               ? (uint32_t)(info.id_NumBlocks - info.id_NumBlocksUsed) : 0u;
    bytesPerBlock = (uint32_t)info.id_BytesPerBlock;
    // Saturate in 32-bit (no 64-bit multiply helper on the 68000).
    if (bytesPerBlock != 0u && freeBlocks > AMIGA_MAX_U32 / bytesPerBlock) {
        return AMIGA_MAX_U32;
    }
    return freeBlocks * bytesPerBlock;
}


bool jlpSaveDelete(const char *path) {
    return DeleteFile((CONST_STRPTR)path) != 0;
}


bool jlpSaveDirEnsure(const char *dir) {
    BPTR  lock;

    lock = CreateDir((CONST_STRPTR)dir);
    if (lock != 0) {
        UnLock(lock);
        return true;
    }
    // CreateDir fails if the directory already exists -- confirm via Lock.
    lock = Lock((CONST_STRPTR)dir, SHARED_LOCK);
    if (lock != 0) {
        UnLock(lock);
        return true;
    }
    return false;
}
