// Sharp X68000 save-file + disk-space HAL.
//
// Structurally the Atari ST HAL (src/atarist/save.c): SAVES/ is a real
// subdirectory next to the .X, delete is stdio remove(), and free space comes
// from the OS. Human68k's _dos_dskfre is the Dfree equivalent.

#include <stdio.h>

#include <x68k/dos.h>

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


#define X68K_DRIVE_CURRENT  0       // _dos_dskfre drive 0 = current drive
#define X68K_MAX_U32        0xFFFFFFFFu


uint32_t jlpDiskFree(void) {
    struct dos_freeinf info;
    uint32_t           bytesPerClus;

    // Negative return is an error (bad drive, no media).
    if (_dos_dskfre(X68K_DRIVE_CURRENT, &info) < 0) {
        return 0u;
    }
    // free = free clusters, sec = sectors per cluster, byte = bytes per sector.
    // Saturate rather than wrap: no 64-bit multiply helper on the 68000, and
    // a 1.2 MB floppy cannot overflow this anyway -- the guard is for hard
    // disks, where free * secPerClus * bytesPerSec genuinely can.
    bytesPerClus = (uint32_t)info.sec * (uint32_t)info.byte;
    if (bytesPerClus != 0u && (uint32_t)info.free > X68K_MAX_U32 / bytesPerClus) {
        return X68K_MAX_U32;
    }
    return (uint32_t)info.free * bytesPerClus;
}


bool jlpSaveDelete(const char *path) {
    return remove(path) == 0;
}


bool jlpSaveDirEnsure(const char *dir) {
    int rc;

    // "Already exists" is the common case and is success for us, so accept
    // _DOSE_EXISTDIR (-20) alongside a clean create. Note the neighbouring
    // _DOSE_EXISTFILE is -80 -- easy to transpose, and it means something
    // else entirely (a FILE of that name is in the way, which IS a failure).
    rc = _dos_mkdir(dir);
    return rc >= 0 || rc == _DOSE_EXISTDIR;
}
