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

#include <fcntl.h>
#include <sys/stat.h>

#include "dirent-util.h"
#include "path-util.h"
#include "stat-util.h"
#include "string-util.h"

int dirent_ensure_type(int dir_fd, struct dirent *de) {
        STRUCT_STATX_DEFINE(sx);
        int r;

        assert(dir_fd >= 0);
        assert(de);

        if (de->d_type != DT_UNKNOWN)
                return 0;

        if (dot_or_dot_dot(de->d_name)) {
                de->d_type = DT_DIR;
                return 0;
        }

        /* Let's ask only for the type, nothing else. */
        r = statx_fallback(dir_fd, de->d_name, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_TYPE, &sx);
        if (r < 0)
                return r;

        assert(FLAGS_SET(sx.stx_mask, STATX_TYPE));
        de->d_type = IFTODT(sx.stx_mode);

        /* If the inode is passed too, update the field, i.e. report most recent data */
        if (FLAGS_SET(sx.stx_mask, STATX_INO))
                de->d_ino = sx.stx_ino;

        return 0;
}

bool dirent_is_file(const struct dirent *de) {
        assert(de);

        if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN))
                return false;

        if (hidden_or_backup_file(de->d_name))
                return false;

        return true;
}

bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
        assert(de);

        if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN))
                return false;

        if (de->d_name[0] == '.')
                return false;

        if (!suffix)
                return true;

        return endswith(de->d_name, suffix);
}

struct dirent *readdir_ensure_type(DIR *d) {
        int r;

        assert(d);

        /* Like readdir(), but fills in .d_type if it is DT_UNKNOWN */

        for (;;) {
                struct dirent *de;

                errno = 0;
                de = readdir(d);
                if (!de)
                        return NULL;

                r = dirent_ensure_type(dirfd(d), de);
                if (r >= 0)
                        return de;
                if (r != -ENOENT) {
                        errno = -r; /* We want to be compatible with readdir(), hence propagate error via errno here */
                        return NULL;
                }

                /* Vanished by now? Then skip immediately to next */
        }
}

struct dirent *readdir_no_dot(DIR *d) {
        assert(d);

        for (;;) {
                struct dirent *de;

                de = readdir_ensure_type(d);
                if (!de || !dot_or_dot_dot(de->d_name))
                        return de;
        }
}
