// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020 Bootlin
 *
 * Author: Joao Marcos Costa <joaomarcos.costa@bootlin.com>
 */

#include <asm/unaligned.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sqfs_decompressor.h"
#include "sqfs_filesystem.h"
#include "sqfs_utils.h"

int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size)
{
	switch (get_unaligned_le16(&inode->inode_type)) {
	case SQFS_DIR_TYPE:
		return sizeof(struct squashfs_dir_inode);

	case SQFS_REG_TYPE: {
		struct squashfs_reg_inode *reg =
			(struct squashfs_reg_inode *)inode;
		u32 fragment = get_unaligned_le32(&reg->fragment);
		u32 file_size = get_unaligned_le32(&reg->file_size);
		unsigned int blk_list_size;

		if (SQFS_IS_FRAGMENTED(fragment))
			blk_list_size = file_size / blk_size;
		else
			blk_list_size = DIV_ROUND_UP(file_size, blk_size);

		return sizeof(*reg) + blk_list_size * sizeof(u32);
	}

	case SQFS_LDIR_TYPE: {
		struct squashfs_ldir_inode *ldir =
			(struct squashfs_ldir_inode *)inode;
		u16 i_count = get_unaligned_le16(&ldir->i_count);
		unsigned int index_list_size = 0, l = 0;
		struct squashfs_directory_index *di;
		u32 sz;

		if (i_count == 0)
			return sizeof(*ldir);

		di = ldir->index;
		while (l < i_count + 1) {
			sz = get_unaligned_le32(&di->size) + 1;
			index_list_size += sz;
			di = (void *)di + sizeof(*di) + sz;
			l++;
		}

		return sizeof(*ldir) + index_list_size +
			(i_count + 1) * SQFS_DIR_INDEX_BASE_LENGTH;
	}

	case SQFS_LREG_TYPE: {
		struct squashfs_lreg_inode *lreg =
			(struct squashfs_lreg_inode *)inode;
		u32 fragment = get_unaligned_le32(&lreg->fragment);
		u64 file_size = get_unaligned_le64(&lreg->file_size);
		unsigned int blk_list_size;

		if (fragment == 0xFFFFFFFF)
			blk_list_size = DIV_ROUND_UP(file_size, blk_size);
		else
			blk_list_size = file_size / blk_size;

		return sizeof(*lreg) + blk_list_size * sizeof(u32);
	}

	case SQFS_SYMLINK_TYPE:
	case SQFS_LSYMLINK_TYPE: {
		struct squashfs_symlink_inode *symlink =
			(struct squashfs_symlink_inode *)inode;

		return sizeof(*symlink) +
			get_unaligned_le32(&symlink->symlink_size);
	}

	case SQFS_BLKDEV_TYPE:
	case SQFS_CHRDEV_TYPE:
		return sizeof(struct squashfs_dev_inode);
	case SQFS_LBLKDEV_TYPE:
	case SQFS_LCHRDEV_TYPE:
		return sizeof(struct squashfs_ldev_inode);
	case SQFS_FIFO_TYPE:
	case SQFS_SOCKET_TYPE:
		return sizeof(struct squashfs_ipc_inode);
	case SQFS_LFIFO_TYPE:
	case SQFS_LSOCKET_TYPE:
		return sizeof(struct squashfs_lipc_inode);
	default:
		printf("Error while searching inode: unknown type.\n");
		return -EINVAL;
	}
}

/*
 * Given the uncompressed inode table, the inode to be found and the number of
 * inodes in the table, return inode position in case of success.
 */
void *sqfs_find_inode(void *inode_table, int inode_number, __le32 inode_count,
		      __le32 block_size)
{
	struct squashfs_base_inode *base;
	unsigned int offset = 0, k;
	int sz;

	if (!inode_table) {
		printf("%s: Invalid pointer to inode table.\n", __func__);
		return NULL;
	}

	for (k = 0; k < le32_to_cpu(inode_count); k++) {
		base = inode_table + offset;
		if (get_unaligned_le32(&base->inode_number) == inode_number)
			return inode_table + offset;

		sz = sqfs_inode_size(base, le32_to_cpu(block_size));
		if (sz < 0)
			return NULL;

		offset += sz;
	}

	printf("Inode not found.\n");

	return NULL;
}

int sqfs_read_metablock(unsigned char *file_mapping, int offset,
			bool *compressed, u32 *data_size)
{
	const unsigned char *data;
	u16 header;

	if (!file_mapping)
		return -EFAULT;
	data = file_mapping + offset;

	header = get_unaligned((u16 *)data);
	if (!header)
		return -EINVAL;

	*compressed = SQFS_COMPRESSED_METADATA(header);
	*data_size = SQFS_METADATA_SIZE(header);

	if (*data_size > SQFS_METADATA_BLOCK_SIZE) {
		printf("Invalid metatada block size: %d bytes.\n", *data_size);
		return -EINVAL;
	}

	return 0;
}
