/*
 * 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 <fs/fs.h>
#include <fs/types.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

static struct fs_mp *find(const char *const path, size_t *const out)
{
    struct fs_mp *ret = NULL;
    size_t n = 0;

    for (const struct fs_mountpoint *p = fs_mphead; p; p = p->next)
    {
        const size_t len = strlen(p->tgt);

        if (!strncmp(p->tgt, path, len))
        {
            const size_t sz = n + 1;
            struct fs_mp *const m = realloc(ret, sz * sizeof *m);

            if (!m)
                goto failure;

            m[n++] = (const struct fs_mp)
            {
                .fs = p->fs,
                .prv = p->prv,
                .src = p->src,
                .tgt = p->tgt
            };

            ret = m;
        }
    }

    *out = n;
    return ret;

failure:
    free(ret);
    return NULL;
}

static void sort(struct fs_mp *const m, const size_t n)
{
    for (size_t i = 1; i < n; i++)
    {
        struct fs_mp am = m[i];
        const size_t len = strlen(am.tgt);
        size_t j = i;

        while (j && len < strlen(m[j - 1].tgt))
        {
            m[j] = m [j - 1];
            j--;
        }

        m[j] = am;
    }
}

struct fs_mp *fs_mps_from_path(const char *const path, size_t *const n)
{
    struct fs_mp *const ret = find(path, n);

    if (!ret)
        return NULL;

    sort(ret, *n);
    return ret;
}
