// SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
#include "erofs/print.h"
#include "erofs/dir.h"
#include <stdlib.h>
#include <sys/stat.h>

static int traverse_dirents(struct erofs_dir_context *ctx,
			    void *dentry_blk, unsigned int lblk,
			    unsigned int next_nameoff, unsigned int maxsize,
			    bool fsck)
{
	struct erofs_dirent *de = dentry_blk;
	const struct erofs_dirent *end = dentry_blk + next_nameoff;
	const char *prev_name = NULL;
	const char *errmsg;
	unsigned int prev_namelen = 0;
	int ret = 0;
	bool silent = false;

	while (de < end) {
		const char *de_name;
		unsigned int de_namelen;
		unsigned int nameoff;

		nameoff = le16_to_cpu(de->nameoff);
		de_name = (char *)dentry_blk + nameoff;

		/* the last dirent check */
		if (de + 1 >= end)
			de_namelen = strnlen(de_name, maxsize - nameoff);
		else
			de_namelen = le16_to_cpu(de[1].nameoff) - nameoff;

		ctx->de_nid = le64_to_cpu(de->nid);
		erofs_dbg("traversed nid (%llu)", ctx->de_nid | 0ULL);

		ret = -EFSCORRUPTED;
		/* corrupted entry check */
		if (nameoff != next_nameoff) {
			errmsg = "bogus dirent nameoff";
			break;
		}

		if (nameoff + de_namelen > maxsize ||
				de_namelen > EROFS_NAME_LEN) {
			errmsg = "bogus dirent namelen";
			break;
		}

		if (fsck && prev_name) {
			int cmp = strncmp(prev_name, de_name,
					  min(prev_namelen, de_namelen));

			if (cmp > 0 || (cmp == 0 &&
					prev_namelen >= de_namelen)) {
				errmsg = "wrong dirent name order";
				break;
			}
		}

		if (fsck && de->file_type >= EROFS_FT_MAX) {
			errmsg = "invalid file type %u";
			break;
		}

		ctx->dname = de_name;
		ctx->de_namelen = de_namelen;
		ctx->de_ftype = de->file_type;
		ctx->dot_dotdot = is_dot_dotdot_len(de_name, de_namelen);
		if (ctx->dot_dotdot) {
			switch (de_namelen) {
			case 2:
				if (fsck &&
				    (ctx->flags & EROFS_READDIR_DOTDOT_FOUND)) {
					errmsg = "duplicated `..' dirent";
					goto out;
				}
				ctx->flags |= EROFS_READDIR_DOTDOT_FOUND;
				if (sbi.root_nid == ctx->dir->nid) {
					ctx->pnid = sbi.root_nid;
					ctx->flags |= EROFS_READDIR_VALID_PNID;
				}
				if (fsck &&
				    (ctx->flags & EROFS_READDIR_VALID_PNID) &&
				    ctx->de_nid != ctx->pnid) {
					errmsg = "corrupted `..' dirent";
					goto out;
				}
				break;
			case 1:
				if (fsck &&
				    (ctx->flags & EROFS_READDIR_DOT_FOUND)) {
					errmsg = "duplicated `.' dirent";
					goto out;
				}

				ctx->flags |= EROFS_READDIR_DOT_FOUND;
				if (fsck && ctx->de_nid != ctx->dir->nid) {
					errmsg = "corrupted `.' dirent";
					goto out;
				}
				break;
			}
		}
		ret = ctx->cb(ctx);
		if (ret) {
			silent = true;
			break;
		}
		prev_name = de_name;
		prev_namelen = de_namelen;
		next_nameoff += de_namelen;
		++de;
	}
out:
	if (ret && !silent)
		erofs_err("%s @ nid %llu, lblk %u, index %lu",
			  errmsg, ctx->dir->nid | 0ULL, lblk,
			  (de - (struct erofs_dirent *)dentry_blk) | 0UL);
	return ret;
}

int erofs_iterate_dir(struct erofs_dir_context *ctx, bool fsck)
{
	struct erofs_inode *dir = ctx->dir;
	int err = 0;
	erofs_off_t pos;
	char buf[EROFS_BLKSIZ];

	if ((dir->i_mode & S_IFMT) != S_IFDIR)
		return -ENOTDIR;

	ctx->flags &= ~EROFS_READDIR_ALL_SPECIAL_FOUND;
	pos = 0;
	while (pos < dir->i_size) {
		erofs_blk_t lblk = erofs_blknr(pos);
		erofs_off_t maxsize = min_t(erofs_off_t,
					dir->i_size - pos, EROFS_BLKSIZ);
		const struct erofs_dirent *de = (const void *)buf;
		unsigned int nameoff;

		err = erofs_pread(dir, buf, maxsize, pos);
		if (err) {
			erofs_err("I/O error occurred when reading dirents @ nid %llu, lblk %u: %d",
				  dir->nid | 0ULL, lblk, err);
			return err;
		}

		nameoff = le16_to_cpu(de->nameoff);
		if (nameoff < sizeof(struct erofs_dirent) ||
		    nameoff >= PAGE_SIZE) {
			erofs_err("invalid de[0].nameoff %u @ nid %llu, lblk %u",
				  nameoff, dir->nid | 0ULL, lblk);
			return -EFSCORRUPTED;
		}
		err = traverse_dirents(ctx, buf, lblk, nameoff, maxsize, fsck);
		if (err)
			break;
		pos += maxsize;
	}

	if (fsck && (ctx->flags & EROFS_READDIR_ALL_SPECIAL_FOUND) !=
			EROFS_READDIR_ALL_SPECIAL_FOUND) {
		erofs_err("`.' or `..' dirent is missing @ nid %llu",
			  dir->nid | 0ULL);
		return -EFSCORRUPTED;
	}
	return err;
}
