/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "analyze.h"
#include "analyze-filesystems.h"
#include "fileio.h"
#include "filesystems.h"
#include "set.h"
#include "strv.h"
#include "terminal-util.h"

static int load_available_kernel_filesystems(Set **ret) {
        _cleanup_set_free_ Set *filesystems = NULL;
        _cleanup_free_ char *t = NULL;
        int r;

        assert(ret);

        /* Let's read the available filesystems */

        r = read_virtual_file("/proc/filesystems", SIZE_MAX, &t, NULL);
        if (r < 0)
                return r;

        for (int i = 0;;) {
                _cleanup_free_ char *line = NULL;
                const char *p;

                r = string_extract_line(t, i++, &line);
                if (r < 0)
                        return log_oom();
                if (r == 0)
                        break;

                if (!line)
                        line = t;

                p = strchr(line, '\t');
                if (!p)
                        continue;

                p += strspn(p, WHITESPACE);

                r = set_put_strdup(&filesystems, p);
                if (r < 0)
                        return log_error_errno(r, "Failed to add filesystem to list: %m");
        }

        *ret = TAKE_PTR(filesystems);
        return 0;
}

static void filesystem_set_remove(Set *s, const FilesystemSet *set) {
        NULSTR_FOREACH(filesystem, set->value) {
                if (filesystem[0] == '@')
                        continue;

                free(set_remove(s, filesystem));
        }
}

static void dump_filesystem_set(const FilesystemSet *set) {
        int r;

        if (!set)
                return;

        printf("%s%s%s\n"
               "    # %s\n",
               ansi_highlight(),
               set->name,
               ansi_normal(),
               set->help);

        NULSTR_FOREACH(filesystem, set->value) {
                const statfs_f_type_t *magic;

                if (filesystem[0] == '@') {
                        printf("    %s%s%s\n", ansi_underline(), filesystem, ansi_normal());
                        continue;
                }

                r = fs_type_from_string(filesystem, &magic);
                assert_se(r >= 0);

                printf("    %s", filesystem);

                for (size_t i = 0; magic[i] != 0; i++) {
                        const char *primary;
                        if (i == 0)
                                printf(" %s(magic: ", ansi_grey());
                        else
                                printf(", ");

                        printf("0x%llx", (unsigned long long) magic[i]);

                        primary = fs_type_to_string(magic[i]);
                        if (primary && !streq(primary, filesystem))
                                printf("[%s]", primary);

                        if (magic[i+1] == 0)
                                printf(")%s", ansi_normal());
                }

                printf("\n");
        }
}

int verb_filesystems(int argc, char *argv[], void *userdata) {
        bool first = true;

#if ! HAVE_LIBBPF
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Not compiled with libbpf support, sorry.");
#endif

        pager_open(arg_pager_flags);

        if (strv_isempty(strv_skip(argv, 1))) {
                _cleanup_set_free_ Set *kernel = NULL, *known = NULL;
                int k;

                NULSTR_FOREACH(fs, filesystem_sets[FILESYSTEM_SET_KNOWN].value)
                        if (set_put_strdup(&known, fs) < 0)
                                return log_oom();

                k = load_available_kernel_filesystems(&kernel);

                for (FilesystemGroups i = 0; i < _FILESYSTEM_SET_MAX; i++) {
                        const FilesystemSet *set = filesystem_sets + i;
                        if (!first)
                                puts("");

                        dump_filesystem_set(set);
                        filesystem_set_remove(kernel, set);
                        if (i != FILESYSTEM_SET_KNOWN)
                                filesystem_set_remove(known, set);
                        first = false;
                }

                if (arg_quiet)  /* Let's not show the extra stuff in quiet mode */
                        return 0;

                if (!set_isempty(known)) {
                        _cleanup_free_ char **l = NULL;

                        printf("\n"
                               "# %sUngrouped filesystems%s (known but not included in any of the groups except @known):\n",
                               ansi_highlight(), ansi_normal());

                        l = set_get_strv(known);
                        if (!l)
                                return log_oom();

                        strv_sort(l);

                        STRV_FOREACH(filesystem, l) {
                                const statfs_f_type_t *magic;
                                bool is_primary = false;

                                assert_se(fs_type_from_string(*filesystem, &magic) >= 0);

                                for (size_t i = 0; magic[i] != 0; i++) {
                                        const char *primary;

                                        primary = fs_type_to_string(magic[i]);
                                        assert(primary);

                                        if (streq(primary, *filesystem))
                                                is_primary = true;
                                }

                                if (!is_primary) {
                                        log_debug("Skipping ungrouped file system '%s', because it's an alias for another one.", *filesystem);
                                        continue;
                                }

                                printf("#   %s\n", *filesystem);
                        }
                }

                if (k < 0) {
                        fputc('\n', stdout);
                        fflush(stdout);
                        log_notice_errno(k, "# Not showing unlisted filesystems, couldn't retrieve kernel filesystem list: %m");
                } else if (!set_isempty(kernel)) {
                        _cleanup_free_ char **l = NULL;

                        printf("\n"
                               "# %sUnlisted filesystems%s (available to the local kernel, but not included in any of the groups listed above):\n",
                               ansi_highlight(), ansi_normal());

                        l = set_get_strv(kernel);
                        if (!l)
                                return log_oom();

                        strv_sort(l);

                        STRV_FOREACH(filesystem, l)
                                printf("#   %s\n", *filesystem);
                }
        } else
                STRV_FOREACH(name, strv_skip(argv, 1)) {
                        const FilesystemSet *set;

                        if (!first)
                                puts("");

                        set = filesystem_set_find(*name);
                        if (!set) {
                                /* make sure the error appears below normal output */
                                fflush(stdout);

                                return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
                                                       "Filesystem set \"%s\" not found.", *name);
                        }

                        dump_filesystem_set(set);
                        first = false;
                }

        return EXIT_SUCCESS;
}
