/*
 * wnix, a Unix-like operating system for WebAssembly applications.
 * Copyright (C) 2025  Xavier Del Campo Romero
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#include <net.h>
#include <net/ops.h>
#include <net/types.h>
#include <aio.h>
#include <loop.h>
#include <wip/wip.h>
#include <fcntl.h>
#include <stdbool.h>

static int open_done(const enum state state, void *const args)
{
    struct net *const n = &net;

    if (loop_rm_aio(n->aio))
        return -1;

    aio_free(n->aio);
    n->aio = NULL;
    n->init = true;
    return 0;
}

int net_init(const char *const dev)
{
    struct net *const n = &net;
    struct aio *aio = NULL;
    const struct wip_cfg cfg =
    {
        .alloc = net_alloc,
        .realloc = net_realloc,
        .free = net_free,
        .read = net_read,
        .write = net_write,
        .user = n
    };

    const struct fs_open op =
    {
        .path = dev,
        .fd = &n->fd,
        .flags = O_RDWR
    };

    const struct aio_done d =
    {
        .f = open_done,
        .args = n
    };

    if (!(aio = aio_open(&op, &d)) || loop_add_aio(aio))
        goto failure;

    *n = (const struct net){.aio = aio};
    wip_init(&n->w, &cfg);
    return 0;

failure:
    aio_free(aio);
    return -1;
}
