// SPDX-License-Identifier: GPL-2.0+
#include "internal.h"
#include <fs_internal.h>

struct erofs_sb_info sbi;

static struct erofs_ctxt {
	struct disk_partition cur_part_info;
	struct blk_desc *cur_dev;
} ctxt;

int erofs_dev_read(int device_id, void *buf, u64 offset, size_t len)
{
	lbaint_t sect = offset >> ctxt.cur_dev->log2blksz;
	int off = offset & (ctxt.cur_dev->blksz - 1);

	if (!ctxt.cur_dev)
		return -EIO;

	if (fs_devread(ctxt.cur_dev, &ctxt.cur_part_info, sect,
		       off, len, buf))
		return 0;
	return -EIO;
}

int erofs_blk_read(void *buf, erofs_blk_t start, u32 nblocks)
{
	return erofs_dev_read(0, buf, blknr_to_addr(start),
			 blknr_to_addr(nblocks));
}

int erofs_probe(struct blk_desc *fs_dev_desc,
		struct disk_partition *fs_partition)
{
	int ret;

	ctxt.cur_dev = fs_dev_desc;
	ctxt.cur_part_info = *fs_partition;

	ret = erofs_read_superblock();
	if (ret)
		goto error;

	return 0;
error:
	ctxt.cur_dev = NULL;
	return ret;
}

struct erofs_dir_stream {
	struct fs_dir_stream fs_dirs;
	struct fs_dirent dirent;

	struct erofs_inode inode;
	char dblk[EROFS_BLKSIZ];
	unsigned int maxsize, de_end;
	erofs_off_t pos;
};

static int erofs_readlink(struct erofs_inode *vi)
{
	size_t len = vi->i_size;
	char *target;
	int err;

	target = malloc(len + 1);
	if (!target)
		return -ENOMEM;
	target[len] = '\0';

	err = erofs_pread(vi, target, len, 0);
	if (err)
		goto err_out;

	err = erofs_ilookup(target, vi);
	if (err)
		goto err_out;

err_out:
	free(target);
	return err;
}

int erofs_opendir(const char *filename, struct fs_dir_stream **dirsp)
{
	struct erofs_dir_stream *dirs;
	int err;

	dirs = calloc(1, sizeof(*dirs));
	if (!dirs)
		return -ENOMEM;

	err = erofs_ilookup(filename, &dirs->inode);
	if (err)
		goto err_out;

	if (S_ISLNK(dirs->inode.i_mode)) {
		err = erofs_readlink(&dirs->inode);
		if (err)
			goto err_out;
	}

	if (!S_ISDIR(dirs->inode.i_mode)) {
		err = -ENOTDIR;
		goto err_out;
	}
	*dirsp = (struct fs_dir_stream *)dirs;
	return 0;
err_out:
	free(dirs);
	return err;
}

int erofs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp)
{
	struct erofs_dir_stream *dirs = (struct erofs_dir_stream *)fs_dirs;
	struct fs_dirent *dent = &dirs->dirent;
	erofs_off_t pos = dirs->pos;
	unsigned int nameoff, de_namelen;
	struct erofs_dirent *de;
	char *de_name;
	int err;

	if (pos >= dirs->inode.i_size)
		return 1;

	if (!dirs->maxsize) {
		dirs->maxsize = min_t(unsigned int, EROFS_BLKSIZ,
				      dirs->inode.i_size - pos);

		err = erofs_pread(&dirs->inode, dirs->dblk,
				  dirs->maxsize, pos);
		if (err)
			return err;

		de = (struct erofs_dirent *)dirs->dblk;
		dirs->de_end = le16_to_cpu(de->nameoff);
		if (dirs->de_end < sizeof(struct erofs_dirent) ||
		    dirs->de_end >= EROFS_BLKSIZ) {
			erofs_err("invalid de[0].nameoff %u @ nid %llu",
				  dirs->de_end, de->nid | 0ULL);
			return -EFSCORRUPTED;
		}
	}

	de = (struct erofs_dirent *)(dirs->dblk + erofs_blkoff(pos));
	nameoff = le16_to_cpu(de->nameoff);
	de_name = (char *)dirs->dblk + nameoff;

	/* the last dirent in the block? */
	if (de + 1 >= (struct erofs_dirent *)(dirs->dblk + dirs->de_end))
		de_namelen = strnlen(de_name, dirs->maxsize - nameoff);
	else
		de_namelen = le16_to_cpu(de[1].nameoff) - nameoff;

	/* a corrupted entry is found */
	if (nameoff + de_namelen > dirs->maxsize ||
	    de_namelen > EROFS_NAME_LEN) {
		erofs_err("bogus dirent @ nid %llu", de->nid | 0ULL);
		DBG_BUGON(1);
		return -EFSCORRUPTED;
	}

	memcpy(dent->name, de_name, de_namelen);
	dent->name[de_namelen] = '\0';

	if (de->file_type == EROFS_FT_DIR) {
		dent->type = FS_DT_DIR;
	} else if (de->file_type == EROFS_FT_SYMLINK) {
		dent->type = FS_DT_LNK;
	} else {
		struct erofs_inode vi;

		dent->type = FS_DT_REG;
		vi.nid = de->nid;

		err = erofs_read_inode_from_disk(&vi);
		if (err)
			return err;
		dent->size = vi.i_size;
	}
	*dentp = dent;

	pos += sizeof(*de);
	if (erofs_blkoff(pos) >= dirs->de_end) {
		pos = blknr_to_addr(erofs_blknr(pos) + 1);
		dirs->maxsize = 0;
	}
	dirs->pos = pos;
	return 0;
}

void erofs_closedir(struct fs_dir_stream *fs_dirs)
{
	free(fs_dirs);
}

int erofs_exists(const char *filename)
{
	struct erofs_inode vi;
	int err;

	err = erofs_ilookup(filename, &vi);
	return err == 0;
}

int erofs_size(const char *filename, loff_t *size)
{
	struct erofs_inode vi;
	int err;

	err = erofs_ilookup(filename, &vi);
	if (err)
		return err;
	*size = vi.i_size;
	return 0;
}

int erofs_read(const char *filename, void *buf, loff_t offset, loff_t len,
	       loff_t *actread)
{
	struct erofs_inode vi;
	int err;

	err = erofs_ilookup(filename, &vi);
	if (err)
		return err;

	if (S_ISLNK(vi.i_mode)) {
		err = erofs_readlink(&vi);
		if (err)
			return err;
	}

	if (!len)
		len = vi.i_size;

	err = erofs_pread(&vi, buf, len, offset);
	if (err) {
		*actread = 0;
		return err;
	}

	if (offset >= vi.i_size)
		*actread = 0;
	else if (offset + len > vi.i_size)
		*actread = vi.i_size - offset;
	else
		*actread = len;
	return 0;
}

void erofs_close(void)
{
	ctxt.cur_dev = NULL;
}

int erofs_uuid(char *uuid_str)
{
	if (IS_ENABLED(CONFIG_LIB_UUID)) {
		if (ctxt.cur_dev)
			uuid_bin_to_str(sbi.uuid, uuid_str,
					UUID_STR_FORMAT_STD);
		return 0;
	}
	return -ENOSYS;
}
