/*
 * platform_web.c — Emscripten/WebAssembly stub implementation
 *
 * The web version cannot spawn child processes, so these functions
 * return "not supported". A real implementation would use Emscripten's
 * pthreads or asyncify if ffmpeg integration is needed.
 */

#include "platform.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <errno.h>      /* ENOSYS */
#include <emscripten.h> /* EM_ASM */

/* ── Helpers ─────────────────────────────────────────────────────────── */

static char last_error_msg[256] = { 0 };

static void set_last_error(const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);
    vsnprintf(last_error_msg, sizeof(last_error_msg), fmt, args);
    va_end(args);
}

/* ── Platform API ────────────────────────────────────────────────────── */

PlatformError Platform_SpawnChild(const char *program, const char **argv,
                                  PlatformSpawnHandle *out_handle) {
    (void)program;
    (void)argv;
    set_last_error("Spawning child processes is not supported on the web");
    out_handle->last_error = ENOSYS;
    return PLATFORM_NOT_SUPPORTED;
}

PlatformError Platform_WaitForChild(PlatformSpawnHandle *handle) {
    (void)handle;
    return PLATFORM_NOT_SUPPORTED;
}

SpawnStatus Platform_GetExitStatus(const PlatformSpawnHandle *handle, int *code) {
    (void)handle;
    (void)code;
    return SPAWN_WAITING;
}

void Platform_CloseSpawnHandle(PlatformSpawnHandle *handle) {
    if (!handle) return;
    handle->handle = NULL;
    handle->status = SPAWN_WAITING;
    handle->exit_code = 0;
    handle->last_error = 0;
}

const char *Platform_GetLastErrorMessage(void) {
    return last_error_msg;
}

const char *Platform_GetTempDir(void) {
    /*
     * Emscripten's virtual filesystem: "/" works as root.
     * For persistent downloads/uploads, consider IDBFS mount.
     */
    return "/";
}

void Platform_OfferFileToUser(const char *path) {
    if (!path) return;
    /*
     * The file was just written into the in-memory (MEMFS) filesystem, which
     * the user can't see. Read it back and hand it to the browser as a
     * download, then unlink the temporary copy so we don't leak heap memory.
     */
    EM_ASM({
        var p = UTF8ToString($0);
        try {
            var data = FS.readFile(p);                 // Uint8Array
            var name = p.split('/').pop() || 'download';
            var blob = new Blob([data], { type: 'application/octet-stream' });
            var url  = URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.href = url;
            a.download = name;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            setTimeout(function() { URL.revokeObjectURL(url); }, 1000);
            try { FS.unlink(p); } catch (e) {}
        } catch (e) {
            console.error('rspektrum: download failed for ' + p + ': ' + e);
        }
    }, path);
}
